Análise e Visualização de Dados: Explorando o Mercado de Pizzas¶
Neste projeto, realizamos uma análise detalhada do mercado de pizzas com o objetivo de fornecer insights valiosos para proprietários de pizzarias e empresários do setor alimentício. Utilizamos técnicas de análise de dados e visualizações gráficas para compreender melhor as tendências, preferências dos clientes e padrões sazonais nas vendas de pizzas.
Começamos examinando um extenso conjunto de dados que continha informações sobre vendas de pizzas, incluindo detalhes como data, hora, quantidade, preço unitário, tamanho, categoria, tipo de pizza e ingredientes. Com base nessas informações, formulamos perguntas de negócios relevantes e realizamos análises específicas para respondê-las.
Primeiramente, investigamos a distribuição de tamanhos de pizza vendidos, o que nos permitiu identificar os tamanhos mais populares entre os clientes. Essa análise é fundamental para ajustes no estoque e na produção, garantindo que a oferta de pizzas atenda à demanda do mercado.
Em seguida, exploramos as vendas de pizza ao longo do tempo, buscando padrões sazonais e tendências de crescimento ou decrescimento. Utilizamos métodos estatísticos, como a decomposição de séries temporais, e modelos de regressão linear para compreender melhor esses padrões e prever as vendas futuras.
Além disso, analisamos a média de preço unitário por categoria de pizza, o que nos permitiu entender a percepção de valor dos clientes para diferentes tipos de pizzas. Essa análise é crucial para o desenvolvimento de estratégias de preços competitivos e eficazes.
Por fim, exploramos as combinações de ingredientes mais populares em pedidos de pizza. Identificar essas combinações nos ajudou a entender as preferências dos clientes e orientar a criação de novos sabores de pizza ou promoções baseadas nas preferências do público-alvo.
Por meio dessas análises e visualizações, esperamos fornecer informações valiosas e perspicazes para os profissionais do setor de pizzas, capacitando-os a tomar decisões informadas e estratégicas para impulsionar seus negócios e atender às necessidades dos clientes de forma eficaz.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Carregar os dados
df = pd.read_excel('pizzaria_limpo.xlsx')
df.head(3)
| id_venda | id_pedido | data | hora | quantidade | preco_unitario | preco_total | tamanho | categoria | pizza | ingredientes | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 2015-01-01 | 11:38:36 | 1 | 13.25 | 13.25 | 6 | Clássica | Havaiana | Presunto em Fatias, Abacaxi, Queijo Mussarela |
| 1 | 2 | 2 | 2015-01-01 | 11:57:40 | 1 | 16.00 | 16.00 | 6 | Clássica | Clássica Deluxe | Pepperoni, Cogumelos, Cebolas Vermelhas, Pimen... |
| 2 | 3 | 2 | 2015-01-01 | 11:57:40 | 1 | 18.50 | 18.50 | 8 | Vegetariana | Cinco Queijos | Queijo Mussarela, Queijo Provolone, Queijo Gou... |
1. Qual é o total de vendas por categoria de pizza ao longo do tempo?
Transformação: Agrupar as vendas por categoria de pizza e calcular o total de vendas para cada categoria em intervalos de tempo (diário, semanal, mensal, etc.).
Benefícios: Isso ajudará a identificar quais categorias de pizza são mais populares em diferentes períodos de tempo, possibilitando ajustes no estoque e na estratégia de marketing.
import warnings
warnings.filterwarnings('ignore')
# Converter as colunas 'data' e 'hora' para datetime
df['data'] = pd.to_datetime(df['data'])
df['hora'] = pd.to_datetime(df['hora'])
# Criar uma nova coluna com a data e hora combinadas
df['data_hora'] = df['data'] + pd.to_timedelta(df['hora'].dt.hour, unit='h')
# Agrupar as vendas por categoria de pizza e data
vendas_por_categoria = df.groupby([df['data_hora'].dt.date, 'categoria'])['preco_total'].sum().reset_index()
# Plotar o total de vendas por categoria ao longo do tempo
plt.figure(figsize=(12, 6))
sns.lineplot(data=vendas_por_categoria, x='data_hora', y='preco_total', hue='categoria')
plt.title('Total de Vendas por Categoria de Pizza ao Longo do Tempo')
plt.xlabel('Data')
plt.ylabel('Total de Vendas')
plt.xticks(rotation=45)
plt.tight_layout()
plt.legend(title='Categoria de Pizza')
plt.show()
# Criar uma lista de categorias de pizza únicas
categorias_unicas = df['categoria'].unique()
# Criar subplots 2x2 para cada categoria de pizza separadamente
fig, axs = plt.subplots(2, 2, figsize=(12, 10), sharex=True, sharey=True)
# Iterar sobre cada categoria de pizza e plotar o total de vendas ao longo do tempo
for i, categoria in enumerate(categorias_unicas):
# Filtrar os dados para a categoria atual
dados_categoria = df[df['categoria'] == categoria]
# Agrupar as vendas por data e calcular o total de vendas para cada data
vendas_por_data = dados_categoria.groupby(dados_categoria['data_hora'].dt.date)['preco_total'].sum().reset_index()
# Plotar o gráfico para a categoria atual
sns.lineplot(data=vendas_por_data, x='data_hora', y='preco_total', ax=axs[i//2, i%2])
axs[i//2, i%2].set_title(f'Total de Vendas - {categoria}')
axs[i//2, i%2].set_xlabel('Data')
axs[i//2, i%2].set_ylabel('Total de Vendas')
# Ajustar o layout
plt.tight_layout()
plt.show()
2. Qual é a média de preço total por pedido ao longo do tempo?
Transformação: Calcular o preço total de cada pedido e então calcular a média desses valores em intervalos de tempo.
Benefícios: Isso pode fornecer insights sobre as preferências dos clientes e a disposição de gastar em diferentes momentos, o que pode informar estratégias de preços e promoções.
# Calcular o preço total de cada pedido
df['preco_total_pedido'] = df['quantidade'] * df['preco_total']
# Agrupar os pedidos por data e calcular a média do preço total por pedido
media_preco_total_por_pedido = df.groupby(df['data_hora'].dt.date)['preco_total_pedido'].mean().reset_index()
# Plotar a média de preço total por pedido ao longo do tempo
plt.figure(figsize=(12, 6))
sns.lineplot(data=media_preco_total_por_pedido, x='data_hora', y='preco_total_pedido')
plt.title('Média de Preço Total por Pedido ao Longo do Tempo')
plt.xlabel('Data')
plt.ylabel('Média de Preço Total por Pedido')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
3. Quais são as combinações de ingredientes mais populares em pedidos de pizza?
Transformação: Analisar os ingredientes listados em cada pedido e contar a frequência de cada combinação de ingredientes.
Benefícios: Isso permitirá identificar quais combinações de ingredientes são mais populares entre os clientes, possibilitando a criação de novas pizzas ou promoções com base nas preferências dos clientes.
# Criar uma lista de todos os ingredientes únicos
todos_ingredientes = []
for lista_ingredientes in df['ingredientes']:
ingredientes = lista_ingredientes.split(', ')
todos_ingredientes.extend(ingredientes)
# Contar a frequência de cada combinação de ingredientes
frequencia_ingredientes = pd.Series(todos_ingredientes).value_counts()
# Selecionar as 10 combinações de ingredientes mais populares
top_ingredientes = frequencia_ingredientes.head(10)
# Plotar um gráfico de barras horizontais das combinações de ingredientes mais populares
plt.figure(figsize=(10, 6))
top_ingredientes.sort_values().plot(kind='barh', color='skyblue')
plt.title('Top 10 Combinações de Ingredientes Mais Populares')
plt.xlabel('Número de Pedidos')
plt.ylabel('Combinação de Ingredientes')
plt.tight_layout()
plt.show()
4. Qual é a média de preço unitário por categoria de pizza?
Transformação: Calcular a média do preço unitário para cada categoria de pizza.
Benefícios: Isso pode revelar insights sobre a percepção de valor dos clientes para diferentes tipos de pizza, auxiliando na definição de preços competitivos e estratégias de precificação.
# Calcular a média do preço unitário por categoria de pizza
media_preco_por_categoria = df.groupby('categoria')['preco_unitario'].mean().sort_values()
# Plotar a média do preço unitário por categoria de pizza
plt.figure(figsize=(10, 6))
media_preco_por_categoria.plot(kind='barh', color='skyblue')
plt.title('Média de Preço Unitário por Categoria de Pizza')
plt.xlabel('Preço Unitário Médio')
plt.ylabel('Categoria de Pizza')
plt.grid(axis='x', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
5. Existe alguma sazonalidade nas vendas de pizza?
Transformação: Analisar as vendas ao longo do tempo e identificar padrões sazonais ou tendências.
Benefícios: Compreender a sazonalidade nas vendas de pizza pode ajudar na previsão da demanda, no planejamento de estoque e no ajuste de estratégias de marketing sazonais.
# Agrupar as vendas por mês e calcular o total de vendas
vendas_por_mes = df.resample('M', on='data')['preco_total'].sum()
# Plotar as vendas de pizza ao longo do tempo
plt.figure(figsize=(12, 6))
plt.plot(vendas_por_mes, marker='o', linestyle='-')
plt.title('Vendas de Pizza ao Longo do Tempo')
plt.xlabel('Data')
plt.ylabel('Total de Vendas')
plt.grid(True)
plt.tight_layout()
plt.show()
Para identificar padrões sazonais ou tendências, também podemos usar técnicas como média móvel ou decomposição de séries temporais. Por exemplo, podemos calcular a média móvel de 12 meses para suavizar os dados e identificar tendências de longo prazo.
# Agrupar as vendas por mês e calcular o total de vendas
vendas_por_mes = df.resample('M', on='data')['preco_total'].sum()
# Calcular a média móvel de 12 meses
media_movel = vendas_por_mes.rolling(window=12, min_periods=1).mean() # Adicionamos min_periods=1 para calcular a média móvel mesmo com menos de 12 meses de dados
# Plotar as vendas de pizza e a média móvel ao longo do tempo
plt.figure(figsize=(12, 6))
plt.plot(vendas_por_mes, marker='o', linestyle='-', label='Vendas de Pizza')
plt.plot(media_movel, linestyle='--', color='red', label='Média Móvel (12 meses)')
plt.title('Vendas de Pizza e Média Móvel ao Longo do Tempo')
plt.xlabel('Data')
plt.ylabel('Total de Vendas')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
6. Qual é a distribuição de tamanhos de pizza vendidos?
Transformação: Contar a quantidade de cada tamanho de pizza vendido.
Benefícios: Isso ajudará a entender quais tamanhos de pizza são mais populares entre os clientes, permitindo ajustes no estoque e na produção para atender à demanda.
# Contar a quantidade de cada tamanho de pizza vendido
tamanhos_count = df['tamanho'].value_counts()
# Plotar a distribuição de tamanhos de pizza vendidos
plt.figure(figsize=(8, 6))
tamanhos_count.plot(kind='bar', color='skyblue')
plt.title('Distribuição de Tamanhos de Pizza Vendidos')
plt.xlabel('Tamanho da Pizza')
plt.ylabel('Quantidade Vendida')
plt.xticks(rotation=0)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
# Plotar a distribuição de tamanhos de pizza vendidos em um gráfico de pizza
plt.figure(figsize=(8, 6))
plt.pie(tamanhos_count, labels=tamanhos_count.index, autopct='%1.1f%%', startangle=140, colors=plt.cm.tab20.colors)
plt.title('Distribuição de Tamanhos de Pizza Vendidos')
plt.axis('equal')
plt.tight_layout()
plt.show()
Ajustaremos um modelo de regressão linear simples usando a biblioteca scikit-learn, utilizando a variável de tempo como um indicador do período de vendas.
O modelo de regressão linear foi utilizado para prever as vendas de pizza com base no tempo. Isso nos permite entender melhor as tendências de vendas ao longo do tempo e prever futuras vendas com base nos padrões históricos.
A visualização gerada mostra as vendas reais de pizza ao longo do tempo, representadas pela linha sólida, e a previsão do modelo de regressão linear, representada pela linha tracejada em vermelho. Isso nos permite identificar tendências de crescimento ou decrescimento nas vendas de pizza em relação ao tempo, o que pode ser útil para o planejamento de estoque e produção para atender à demanda dos clientes.
import numpy as np
import statsmodels.api as sm
# Agrupar as vendas por mês e calcular o total de vendas
vendas_por_mes = df.resample('M', on='data')['preco_total'].sum()
# Adicionar uma variável de tempo
vendas_por_mes = pd.DataFrame({'data': vendas_por_mes.index, 'vendas': vendas_por_mes.values})
vendas_por_mes['tempo'] = np.arange(len(vendas_por_mes))
# Adicionar uma constante ao modelo
X = sm.add_constant(vendas_por_mes['tempo'])
# Ajustar um modelo de regressão linear
modelo = sm.OLS(vendas_por_mes['vendas'], X)
resultado = modelo.fit()
# Plotar as vendas de pizza e a previsão do modelo
plt.figure(figsize=(12, 6))
plt.plot(vendas_por_mes['data'], vendas_por_mes['vendas'], marker='o', linestyle='-', label='Vendas de Pizza')
plt.plot(vendas_por_mes['data'], resultado.fittedvalues, linestyle='--', color='red', label='Previsão do Modelo')
plt.title('Vendas de Pizza ao Longo do Tempo e Previsão do Modelo de Regressão Linear')
plt.xlabel('Data')
plt.ylabel('Total de Vendas')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
import numpy as np
from sklearn.linear_model import LinearRegression
# Agrupar as vendas por mês e calcular o total de vendas
vendas_por_mes = df.resample('M', on='data')['preco_total'].sum().reset_index()
# Adicionar uma variável de tempo
vendas_por_mes['tempo'] = np.arange(len(vendas_por_mes))
# Ajustar um modelo de regressão linear
modelo = LinearRegression()
modelo.fit(vendas_por_mes[['tempo']], vendas_por_mes['preco_total'])
# Prever as vendas usando o modelo
vendas_por_mes['previsao'] = modelo.predict(vendas_por_mes[['tempo']])
# Plotar as vendas de pizza e a previsão do modelo
plt.figure(figsize=(12, 6))
plt.plot(vendas_por_mes['data'], vendas_por_mes['preco_total'], marker='o', linestyle='-', label='Vendas de Pizza')
plt.plot(vendas_por_mes['data'], vendas_por_mes['previsao'], linestyle='--', color='red', label='Previsão do Modelo')
plt.title('Vendas de Pizza ao Longo do Tempo e Previsão do Modelo de Regressão Linear')
plt.xlabel('Data')
plt.ylabel('Total de Vendas')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
7. Análise das Combinações de Ingredientes Mais Populares em Pedidos de Pizza
Para entender as preferências dos clientes e identificar as combinações de ingredientes mais populares em pedidos de pizza, realizamos uma análise das combinações de ingredientes presentes em nossos dados. Essa análise nos permite criar novas pizzas ou promoções com base nas preferências dos clientes, contribuindo para a satisfação do cliente e o aumento das vendas.
Nuvem de Palavras para Ingredientes:
A nuvem de palavras abaixo apresenta visualmente as combinações de ingredientes mais populares em nossos pedidos de pizza. Quanto maior o tamanho da palavra, mais frequente é a presença dessa combinação de ingredientes nos pedidos.
Essa visualização nos permite identificar rapidamente os ingredientes mais comuns e suas combinações preferidas pelos clientes. Com base nesses insights, podemos desenvolver novas pizzas ou promoções que atendam às preferências dos clientes e impulsionem as vendas.
Observação: As palavras podem aparecer em diferentes tamanhos devido à sua frequência nos pedidos de pizza. Cada palavra representa um ingrediente presente em nossos dados, e sua presença reflete a popularidade dessa combinação de ingredientes entre nossos clientes.
from wordcloud import WordCloud
# Criar nuvem de palavras para Categoria
categoria_text = ' '.join(df['categoria'])
categoria_cloud = WordCloud(width=800, height=400, background_color='white').generate(categoria_text)
# Plotar a nuvem de palavras para Categoria
plt.figure(figsize=(10, 6))
plt.imshow(categoria_cloud, interpolation='bilinear')
plt.title('Nuvem de Palavras para Categoria de Pizza')
plt.axis('off')
plt.show()
# Criar nuvem de palavras para Pizza
pizza_text = ' '.join(df['pizza'])
pizza_cloud = WordCloud(width=800, height=400, background_color='white').generate(pizza_text)
# Plotar a nuvem de palavras para Pizza
plt.figure(figsize=(10, 6))
plt.imshow(pizza_cloud, interpolation='bilinear')
plt.title('Nuvem de Palavras para Nomes de Pizza')
plt.axis('off')
plt.show()
# Criar nuvem de palavras para Ingredientes
ingredientes_text = ' '.join([str(ingrediente).replace(',', '') for ingrediente in df['ingredientes']])
ingredientes_cloud = WordCloud(width=800, height=400, background_color='white').generate(ingredientes_text)
# Plotar a nuvem de palavras para Ingredientes
plt.figure(figsize=(10, 6))
plt.imshow(ingredientes_cloud, interpolation='bilinear')
plt.title('Nuvem de Palavras para Ingredientes')
plt.axis('off')
plt.show()
# Criar nuvem de palavras para Categoria
categoria_counts = df['categoria'].value_counts()
categoria_cloud = WordCloud(width=800, height=400, background_color='white').generate_from_frequencies(categoria_counts)
# Plotar a nuvem de palavras para Categoria
plt.figure(figsize=(10, 6))
plt.imshow(categoria_cloud, interpolation='bilinear')
plt.title('Nuvem de Palavras para Categoria de Pizza')
plt.axis('off')
plt.show()
# Criar nuvem de palavras para Pizza
pizza_counts = df['pizza'].value_counts()
pizza_cloud = WordCloud(width=800, height=400, background_color='white').generate_from_frequencies(pizza_counts)
# Plotar a nuvem de palavras para Pizza
plt.figure(figsize=(10, 6))
plt.imshow(pizza_cloud, interpolation='bilinear')
plt.title('Nuvem de Palavras para Nomes de Pizza')
plt.axis('off')
plt.show()
# Criar nuvem de palavras para Ingredientes
ingredientes_counts = df['ingredientes'].str.split(', ').explode().value_counts()
ingredientes_cloud = WordCloud(width=800, height=400, background_color='white').generate_from_frequencies(ingredientes_counts)
# Plotar a nuvem de palavras para Ingredientes
plt.figure(figsize=(10, 6))
plt.imshow(ingredientes_cloud, interpolation='bilinear')
plt.title('Nuvem de Palavras para Ingredientes')
plt.axis('off')
plt.show()
df.head(2)
| id_venda | id_pedido | data | hora | quantidade | preco_unitario | preco_total | tamanho | categoria | pizza | ingredientes | data_hora | preco_total_pedido | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 2015-01-01 | 2024-04-06 11:38:36 | 1 | 13.25 | 13.25 | 6 | Clássica | Havaiana | Presunto em Fatias, Abacaxi, Queijo Mussarela | 2015-01-01 11:00:00 | 13.25 |
| 1 | 2 | 2 | 2015-01-01 | 2024-04-06 11:57:40 | 1 | 16.00 | 16.00 | 6 | Clássica | Clássica Deluxe | Pepperoni, Cogumelos, Cebolas Vermelhas, Pimen... | 2015-01-01 11:00:00 | 16.00 |
# Contagem total de categoria e pizzas
sns.countplot(df, x='categoria')
plt.show()
# Calcular a contagem de cada tipo de pizza
contagem_pizzas = df['pizza'].value_counts()
# Ordenar os valores da contagem de pizzas
contagem_pizzas = contagem_pizzas.sort_values(ascending=False)
# Plotar o gráfico de contagem de pizzas ordenado
plt.figure(figsize=(10, 8))
sns.barplot(x=contagem_pizzas.values, y=contagem_pizzas.index, palette='viridis')
plt.xlabel('Quantidade')
plt.ylabel('Tipo de Pizza')
plt.title('Contagem de Vendas por Tipo de Pizza (Ordenado)')
plt.show()
# Checar informações da tabela
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 48620 entries, 0 to 48619 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id_venda 48620 non-null int64 1 id_pedido 48620 non-null int64 2 data 48620 non-null datetime64[ns] 3 hora 48620 non-null datetime64[ns] 4 quantidade 48620 non-null int64 5 preco_unitario 48620 non-null float64 6 preco_total 48620 non-null float64 7 tamanho 48620 non-null int64 8 categoria 48620 non-null object 9 pizza 48620 non-null object 10 ingredientes 48620 non-null object 11 data_hora 48620 non-null datetime64[ns] 12 preco_total_pedido 48620 non-null float64 dtypes: datetime64[ns](3), float64(3), int64(4), object(3) memory usage: 4.8+ MB
# Extrair informações temporais de data e hora
df['dia_semana'] = df['data'].dt.weekday
df['dia'] = df['data'].dt.day
df['mes'] = df['data'].dt.month
df['semana'] = df['data'].dt.isocalendar().week
df['trimestre'] = df['data'].dt.quarter
df['horas'] = df['hora'].dt.hour
df['minuto'] = df['hora'].dt.minute
df['dia_semana'] = df['dia_semana'].map(
{0: 'Segunda', 1: 'Terça', 2: 'Quarta', 3: 'Quinta',
4: 'Sexta', 5: 'Sábado', 6: 'Domingo'}
)
df['semana'] = df['semana'].astype(int)
df.head()
| id_venda | id_pedido | data | hora | quantidade | preco_unitario | preco_total | tamanho | categoria | pizza | ingredientes | data_hora | preco_total_pedido | dia_semana | dia | mes | semana | trimestre | horas | minuto | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 2015-01-01 | 2024-04-06 11:38:36 | 1 | 13.25 | 13.25 | 6 | Clássica | Havaiana | Presunto em Fatias, Abacaxi, Queijo Mussarela | 2015-01-01 11:00:00 | 13.25 | Quinta | 1 | 1 | 1 | 1 | 11 | 38 |
| 1 | 2 | 2 | 2015-01-01 | 2024-04-06 11:57:40 | 1 | 16.00 | 16.00 | 6 | Clássica | Clássica Deluxe | Pepperoni, Cogumelos, Cebolas Vermelhas, Pimen... | 2015-01-01 11:00:00 | 16.00 | Quinta | 1 | 1 | 1 | 1 | 11 | 57 |
| 2 | 3 | 2 | 2015-01-01 | 2024-04-06 11:57:40 | 1 | 18.50 | 18.50 | 8 | Vegetariana | Cinco Queijos | Queijo Mussarela, Queijo Provolone, Queijo Gou... | 2015-01-01 11:00:00 | 18.50 | Quinta | 1 | 1 | 1 | 1 | 11 | 57 |
| 3 | 4 | 2 | 2015-01-01 | 2024-04-06 11:57:40 | 1 | 20.75 | 20.75 | 8 | Suprema | Suprema Italiana | Salame Calabrese, Capocollo, Tomates, Cebolas ... | 2015-01-01 11:00:00 | 20.75 | Quinta | 1 | 1 | 1 | 1 | 11 | 57 |
| 4 | 5 | 2 | 2015-01-01 | 2024-04-06 11:57:40 | 1 | 16.00 | 16.00 | 6 | Vegetariana | Mexicana | Tomates, Pimentões Vermelhos, Pimentões Jalape... | 2015-01-01 11:00:00 | 16.00 | Quinta | 1 | 1 | 1 | 1 | 11 | 57 |
# Contagem por trimestre
sns.countplot(df, x='trimestre');
# Contagem por semana
plt.figure(figsize=(13, 6))
sns.countplot(df, x='semana');
# Contagem por dia do mês
plt.figure(figsize=(13, 6))
sns.countplot(df, x='dia');
# Contagem por dia da semana
plt.figure(figsize=(13, 6))
sns.countplot(df, x='dia_semana');
# Contagem por hora do dia
plt.figure(figsize=(13, 6))
sns.countplot(df, x='horas');
# Estatísticas descritivas básicas
pd.set_option('display.float_format', '{:.2f}'.format)
colunas = ['quantidade', 'preco_unitario', 'preco_total', 'tamanho', 'preco_total_pedido']
df[colunas].describe()
| quantidade | preco_unitario | preco_total | tamanho | preco_total_pedido | |
|---|---|---|---|---|---|
| count | 48620.00 | 48620.00 | 48620.00 | 48620.00 | 48620.00 |
| mean | 1.02 | 16.49 | 16.82 | 6.25 | 17.50 |
| std | 0.14 | 3.62 | 4.44 | 1.76 | 8.59 |
| min | 1.00 | 9.75 | 9.75 | 4.00 | 9.75 |
| 25% | 1.00 | 12.75 | 12.75 | 4.00 | 12.75 |
| 50% | 1.00 | 16.50 | 16.50 | 6.00 | 16.50 |
| 75% | 1.00 | 20.25 | 20.50 | 8.00 | 20.50 |
| max | 4.00 | 35.95 | 83.00 | 16.00 | 332.00 |
Previsão de Demanda de Quantidade de Pizzas Vendidas por Hora¶
Neste projeto, embarcamos em uma jornada analítica para prever a demanda de pizzas vendidas por hora, visando ajudar proprietários de pizzarias e gestores do setor alimentício a otimizar seus processos de produção e estoque.
Começamos coletando e preparando um extenso conjunto de dados que continha informações detalhadas sobre as vendas de pizzas, incluindo data, hora e quantidade vendida por transação. Em seguida, realizamos uma análise exploratória para compreender melhor os padrões temporais e identificar possíveis sazonalidades nas vendas de pizza ao longo do dia.
Utilizamos técnicas avançadas de séries temporais para construir modelos de previsão capazes de antecipar a demanda futura com base nos dados históricos de vendas. Ajustamos modelos de previsão de séries temporais, como ARIMA (AutoRegressive Integrated Moving Average) e modelos de regressão, para capturar tendências e padrões sazonais nas vendas de pizza.
Após treinar nossos modelos de previsão, avaliamos sua precisão e desempenho usando métricas apropriadas, como erro médio absoluto (MAE) e erro médio quadrático (RMSE). Realizamos ajustes nos modelos e refinamos nossas previsões para garantir resultados confiáveis e úteis para tomada de decisão.
Por fim, apresentamos nossas previsões de demanda de quantidade de pizzas vendidas por hora, fornecendo insights valiosos para os gestores do setor alimentício. Essas previsões podem ser utilizadas para otimizar a programação de produção, gerenciamento de estoque e planejamento de recursos humanos, contribuindo para a eficiência operacional e maximização dos lucros.
Ao final deste projeto, esperamos ter fornecido uma solução eficaz e prática para a previsão da demanda de pizzas vendidas por hora, ajudando os profissionais do setor alimentício a enfrentar os desafios de gerenciamento de demanda e aprimorar suas operações comerciais.
# Checar correlações entre quantidade e demais variáveis numéricas
# Calcular as correlações
correlacoes = df.corr(numeric_only=True)['quantidade'].sort_values(ascending=False)
# Imprimir as correlações em texto
print("Correlações com a coluna 'quantidade':")
print(correlacoes)
# Plotar o heatmap das correlações
plt.figure(figsize=(10, 8))
sns.heatmap(df.corr(numeric_only=True), annot=True, cmap='coolwarm', fmt=".2f")
plt.title('Correlações entre as Colunas Numéricas')
plt.show()
Correlações com a coluna 'quantidade': quantidade 1.00 preco_total_pedido 0.87 preco_total 0.54 minuto 0.01 tamanho 0.01 preco_unitario 0.01 trimestre 0.00 semana 0.00 mes 0.00 id_venda 0.00 id_pedido 0.00 dia 0.00 horas -0.06 Name: quantidade, dtype: float64
# Selecionar colunas relevantes
print(df.columns)
df = df[['quantidade', 'pizza','horas', 'dia_semana', 'dia', 'mes', 'semana', 'trimestre']]
df.head()
Index(['id_venda', 'id_pedido', 'data', 'hora', 'quantidade', 'preco_unitario',
'preco_total', 'tamanho', 'categoria', 'pizza', 'ingredientes',
'data_hora', 'preco_total_pedido', 'dia_semana', 'dia', 'mes', 'semana',
'trimestre', 'horas', 'minuto'],
dtype='object')
| quantidade | pizza | horas | dia_semana | dia | mes | semana | trimestre | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1 | Havaiana | 11 | Quinta | 1 | 1 | 1 | 1 |
| 1 | 1 | Clássica Deluxe | 11 | Quinta | 1 | 1 | 1 | 1 |
| 2 | 1 | Cinco Queijos | 11 | Quinta | 1 | 1 | 1 | 1 |
| 3 | 1 | Suprema Italiana | 11 | Quinta | 1 | 1 | 1 | 1 |
| 4 | 1 | Mexicana | 11 | Quinta | 1 | 1 | 1 | 1 |
# Agrupar os dados por hora e somar quantidades
df = df.groupby(['trimestre', 'mes', 'semana', 'dia', 'dia_semana', 'horas'])
df = df[['quantidade']].sum().reset_index()
df
| trimestre | mes | semana | dia | dia_semana | horas | quantidade | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 1 | 1 | Quinta | 11 | 6 |
| 1 | 1 | 1 | 1 | 1 | Quinta | 12 | 17 |
| 2 | 1 | 1 | 1 | 1 | Quinta | 13 | 33 |
| 3 | 1 | 1 | 1 | 1 | Quinta | 14 | 15 |
| 4 | 1 | 1 | 1 | 1 | Quinta | 15 | 14 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 4176 | 4 | 12 | 53 | 31 | Quinta | 19 | 23 |
| 4177 | 4 | 12 | 53 | 31 | Quinta | 20 | 17 |
| 4178 | 4 | 12 | 53 | 31 | Quinta | 21 | 7 |
| 4179 | 4 | 12 | 53 | 31 | Quinta | 22 | 1 |
| 4180 | 4 | 12 | 53 | 31 | Quinta | 23 | 1 |
4181 rows × 7 columns
# Converter dias da semana para representações numéricas (0 = seg, 6 = dom)
df['dia_semana'] = df['dia_semana'].map(
{'Segunda': 0, 'Terça': 1, 'Quarta': 2, 'Quinta': 3, 'Sexta': 4, 'Sábado': 5, 'Domingo': 6}
)
# Separar as variáveis preditivas da variável alvo (quantidade)
X = df.drop('quantidade', axis=1)
y = df['quantidade']
# Dividir a base de dados em conjuntos para treino e validação do modelo
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.2)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
(3344, 6) (837, 6) (3344,) (837,)
Utilizaremos 80% dos dados para treinamento do modelo e 20% para testar a performance.
# Criar e treinar o modelo
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(random_state=0, n_estimators=50)
model.fit(X_train, y_train)
RandomForestRegressor(n_estimators=50, random_state=0)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
RandomForestRegressor(n_estimators=50, random_state=0)
# Realizar previsões no conjunto de validação
y_pred = model.predict(X_test)
# Retirar média da base de treino
media = y_train.mean()
medias = [media] * len(y_test)
print(f'Média da qtd. de pizzas vendidas por hora (base de treino): {media}')
Média da qtd. de pizzas vendidas por hora (base de treino): 11.955442583732058
Utilizaremos as seguintes métricas de avaliação de performance:
- MAE (Erro Médio Absoluto)
- MAPE (Erro Médio Percentual Absoluto)
- R² Score
1. Mean Absolute Error (MAE):
O MAE é uma métrica que calcula a média das diferenças absolutas entre as previsões do modelo e os valores reais.
Fácil interpretação: O MAE representa uma média das diferenças absolutas entre as previsões e os valores reais, o que é intuitivamente compreensível.
Robustez a outliers: Como as diferenças são tomadas de forma absoluta, o MAE não é sensível a outliers extremos.
2. Mean Absolute Percentage Error (MAPE)
O MAPE é uma métrica que calcula a média das diferenças percentuais absolutas entre as previsões do modelo e os valores reais. É útil para entender o erro relativo em relação aos valores reais.
Interpretável em termos percentuais: O MAPE fornece uma medida de erro relativo em relação aos valores reais, facilitando a interpretação do desempenho do modelo em termos percentuais.
Comparação entre diferentes conjuntos de dados: Como o erro é expresso em termos percentuais, é útil para comparar o desempenho do modelo em diferentes conjuntos de dados com escalas diferentes.
3. Coeficiente de Determinação (R2 Score)
O R2 Score, também conhecido como coeficiente de determinação, é uma métrica que indica a proporção da variância dos valores dependentes que é explicada pela regressão linear. Em outras palavras, ele mede a proporção da variabilidade na variável de resposta que é explicada pelo modelo.
Interpretável: O R2 Score fornece uma medida de quão bem o modelo se ajusta aos dados, variando de 0 a 1, onde 1 indica um ajuste perfeito e 0 indica que o modelo não explica nada da variabilidade dos dados.
Comparação com um modelo de referência: É útil para comparar o desempenho do modelo com um modelo de referência simples, como uma linha horizontal que representa a média dos valores reais. Um R2 Score mais alto indica que o modelo é mais capaz de explicar a variabilidade dos dados do que o modelo de referência.
Em resumo, cada uma dessas métricas possui suas vantagens na avaliação da performance de um modelo de previsão de demanda de quantidade de pizzas vendidas por hora. O MAE e o MAPE são úteis para entender o erro absoluto e relativo entre as previsões e os valores reais, enquanto o R2 Score fornece uma medida do quão bem o modelo se ajusta aos dados, em termos de variabilidade explicada. Utilizar uma combinação dessas métricas pode fornecer uma avaliação mais abrangente e informativa do desempenho do modelo.
# Avaliar a performance das médias em dados "não-vistos" com diferentes métricas
from sklearn.metrics import mean_absolute_error, mean_absolute_percentage_error, r2_score
mae_mean = mean_absolute_error(y_test, medias)
mape_mean = mean_absolute_percentage_error(y_test, medias)
r2_mean = r2_score(y_test, medias)
print(f'MAE Média: {mae_mean}')
print(f'MAPE Média: {mape_mean}')
print(f'R2 Média: {r2_mean}')
MAE Média: 5.937192739505982 MAPE Média: 1.2616420476579129 R2 Média: -0.004499021940532533
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(f'MAE Modelo: {mae_model}')
print(f'MAPE Modelo: {mape_model}')
print(f'R2 Modelo: {r2_model}')
MAE Modelo: 5.031111111111111 MAPE Modelo: 0.8374508245521253 R2 Modelo: 0.18425716373334566
# Visualizar valores reais, média e previsões
plt.plot(np.arange(len(y_test)), y_test, label='Valor Real', alpha=0.5)
plt.plot(np.arange(len(y_test)), medias, label='Média', alpha=1)
plt.plot(np.arange(len(y_test)), y_pred, label='Previsão', alpha=0.5)
plt.legend();
# Ajuste e tunagem de hiperparâmetros do modelo para melhorar a performance
from sklearn.model_selection import GridSearchCV
# Definindo os hiperparâmetros que gostaríamos de sintonizar
param_grid = {
'n_estimators': [50, 100, 200, 300],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# Criando o modelo RandomForestRegressor
rf = RandomForestRegressor(random_state=42)
# Criando um objeto GridSearchCV
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2)
# Ajustando o modelo aos dados de treinamento
grid_search.fit(X_train, y_train)
# Obtendo o melhor modelo
best_rf = grid_search.best_estimator_
# Avaliando o modelo nos dados de teste
test_score = best_rf.score(X_test, y_test)
print("Melhores hiperparâmetros encontrados:", grid_search.best_params_)
print("Desempenho do modelo nos dados de teste:", test_score)
Fitting 5 folds for each of 108 candidates, totalling 540 fits
Melhores hiperparâmetros encontrados: {'max_depth': 10, 'min_samples_leaf': 4, 'min_samples_split': 10, 'n_estimators': 300}
Desempenho do modelo nos dados de teste: 0.3046197843174371
# Definindo os hiperparâmetros que gostaríamos de sintonizar
param_grid = {
'n_estimators': [300, 400, 500],
}
# Criando o modelo RandomForestRegressor
rf = RandomForestRegressor(random_state=42, min_samples_leaf=4, min_samples_split=10, max_depth=10)
# Criando um objeto GridSearchCV
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2)
# Ajustando o modelo aos dados de treinamento
grid_search.fit(X_train, y_train)
# Obtendo o melhor modelo
best_rf = grid_search.best_estimator_
# Avaliando o modelo nos dados de teste
test_score = best_rf.score(X_test, y_test)
print("Melhores hiperparâmetros encontrados:", grid_search.best_params_)
print("Desempenho do modelo nos dados de teste:", test_score)
Fitting 5 folds for each of 3 candidates, totalling 15 fits
Melhores hiperparâmetros encontrados: {'n_estimators': 300}
Desempenho do modelo nos dados de teste: 0.3046197843174371
MAE Média: 5.937192739505982
MAE Modelo: 5.031111111111111
MAPE Média: 1.2616420476579129
MAPE Modelo: 0.8374508245521253
R2 Média: -0.004499021940532533
R2 Modelo: 0.18425716373334566
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(f'MAE Modelo: {mae_model}')
print(f'MAPE Modelo: {mape_model}')
print(f'R2 Modelo: {r2_model}')
# Visualizar valores reais, média e previsões
plt.plot(np.arange(len(y_test)), y_test, label='Valor Real', alpha=0.5)
plt.plot(np.arange(len(y_test)), medias, label='Média', alpha=1)
plt.plot(np.arange(len(y_test)), y_pred, label='Previsão', alpha=0.5)
plt.legend();
MAE Modelo: 4.696427433599541 MAPE Modelo: 0.7842515958041641 R2 Modelo: 0.30339413261422876
# Realizar "validação-cruzada manual" para encontrar a melhor divisão de treino/teste
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=x, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.696427433599541 0.7842515958041641 0.30339413261422876 1 4.986856589683025 0.7080192752540814 0.2688236545200555 2 4.837148559742838 0.7050284090129898 0.3123056689751287 3 4.860317847816018 0.7601812880203751 0.30747996757347984 4 5.016759111530567 0.7417201400977181 0.3219746603644925 5 4.82974971784588 0.7572548639464531 0.26711106575757626 6 4.93222759963225 0.7528550147588375 0.2943921881056607 7 5.261279043353336 0.8096307983697277 0.28047234732189275 8 5.095719553434803 0.8259919713271553 0.20534949534432712 9 5.064715113926254 0.8228807198563024 0.26656692301314977 10 5.11379019767697 0.7529943171603031 0.26101670438796676 11 4.8540916988675695 0.7660552410044933 0.2900770259576285 12 4.877137536919778 0.7351026036237911 0.30428121200978475 13 4.811217365630584 0.772970635047408 0.3184981005939136 14 5.23622673557894 0.802651306111283 0.2980047053945716 15 5.022608718578147 0.7615792518113372 0.2779523086297704 16 5.026435874868556 0.7199890538411673 0.3108997019975309 17 4.878849418863748 0.7304820606464638 0.28088490377002795 18 4.897653444419122 0.7919438230627861 0.2848472864774051 19 5.106346839544417 0.7748866150166529 0.2574104200125309 20 5.204849718595554 0.7562711043274964 0.30124709329516997 21 5.0267680396123495 0.7535204943266289 0.3070643648526118 22 4.799535780777459 0.7977450670053656 0.32073760702670184 23 5.088369998605431 0.7616443172578486 0.2565564951348809 24 4.9812349291312366 0.8891087485368476 0.2876646973715965 25 4.940736807596826 0.8220212007163492 0.26784020431773836 26 4.944699298246136 0.8084066528772824 0.2532292381532454 27 5.2580867643721145 0.8136783544677483 0.3031776200180961 28 5.043018214579167 0.7835039124178335 0.2906523999200604 29 5.151879493763403 0.7546954426450306 0.24842837907483173 30 4.967032251473786 0.8114560005820726 0.30137932972623127 31 4.884011293304311 0.7553716685791549 0.23957371806909178 32 4.953792310235583 0.7486842789167412 0.29394176311099274 33 4.877040158397536 0.7353393847197557 0.3134983238088136 34 4.93799456886561 0.6706324022843988 0.3169660610953352 35 4.968071871516176 0.7202933118987918 0.30571955649654303 36 5.030583576283355 0.7894872260691775 0.29836408158297667 37 4.898355066669212 0.7570927994403004 0.2805626858508533 38 5.201601051259157 0.847274495138624 0.27701533983878746 39 4.97385612552371 0.7910969565640348 0.31705239155499965 40 5.132486306281106 0.7764460415962554 0.306296770456397 41 5.061882617710574 0.7513264546491346 0.31029901870967724 42 5.1142489112103355 0.834579746671423 0.26244911819979266 43 5.008413254734249 0.7358566377803203 0.23852031526599948 44 4.821678888071763 0.726265815729694 0.3414086887482316 45 5.129229991560104 0.7376015685939488 0.23478242794669812 46 5.150851110201097 0.7092728052085103 0.2623124590296939 47 5.108046988193355 0.7965280627748746 0.2857544282487191 48 5.023328426748602 0.7267387206895983 0.31630127363344196 49 4.963805600140595 0.8101817235089857 0.339835797400174 50 5.173409631089822 0.7022602085357403 0.26952406100550175 51 5.028037529950328 0.6987679101143756 0.26089914040030004 52 5.019550955263913 0.8266911324534714 0.2538180472115322 53 4.954239034302376 0.7473801565964046 0.308085807577288 54 5.047835623707539 0.7519312870899002 0.29744303496001256 55 4.754850948686873 0.734423471765605 0.3365325773734906 56 5.329307219552325 0.7680053887691958 0.2405438083858521 57 5.058091759695737 0.7295690582153269 0.3074161880388977 58 5.02166088238063 0.8060759747270841 0.28100641604824894 59 5.009621807669579 0.7973547351014084 0.2859281813834864 60 5.294588085638155 0.829024336623241 0.30350482325430506 61 4.824790562747847 0.8606482052324592 0.30995102876900826 62 4.905737516945944 0.8195218341048127 0.3313735606224192 63 5.062290086462061 0.773154507237698 0.3008715151550776 64 5.023845587116285 0.8125367337994772 0.2447889703706836 65 4.984901247550909 0.7374569963480954 0.31326017143654006 66 4.908461486633831 0.7225322540932422 0.30801858432309637 67 4.905845861236024 0.8052585399077798 0.326834398932785 68 5.0165474416248905 0.7697346925986464 0.2655608809202321 69 5.071123803971155 0.8494849165813568 0.24860755780155586 70 4.812597806598278 0.7584025531253751 0.2829397816299307 71 5.118380376235771 0.8235883011084499 0.270405728178125 72 5.0329156838798665 0.7645226313471963 0.32013076329655865 73 4.968482992352103 0.7705158602375968 0.28178386163318014 74 5.1656628118600505 0.7414300987436936 0.2845075319929583 75 5.076843547729661 0.7412208984800152 0.22662140065485614 76 4.804622931660537 0.8036158368073233 0.33607550963873456 77 5.207113908423996 0.8303039943899291 0.3341259455180823 78 4.984119316285998 0.7512646845227775 0.2784402436719081 79 5.084154172970573 0.7743023056789268 0.23928738190639542 80 4.826653199375038 0.7122685818368212 0.31654586033496335 81 4.780538487183366 0.7775727266797752 0.2895182394464817 82 5.066367739155179 0.773148553709469 0.2983889616176342 83 5.150701947539898 0.756825709703642 0.30295737943994305 84 4.748967947576449 0.686911606963046 0.3183212700586199 85 4.7856534092310445 0.7226333296215176 0.3365399341281814 86 4.8664527745732915 0.748086465582205 0.26640463005778414 87 5.101413440437015 0.8097728519814414 0.2525108060495296 88 4.711782549809337 0.7822190969475512 0.2654727548701875 89 4.9723316378524665 0.7117085657384485 0.3026383255434131 90 5.211957283189949 0.7691160221656886 0.2780228250249669 91 4.918250005984928 0.740514193482157 0.3099265231605015 92 5.059947411574883 0.8007164719101754 0.30611271463438494 93 5.174957013937287 0.8230183056157641 0.3275843041398302 94 5.2130778407989125 0.770811185646729 0.2883837830795619 95 4.852206124204468 0.7850538763473441 0.3109602728404264 96 4.955799100279728 0.7593603679350399 0.3109585773233834 97 5.066049935771093 0.7401307721820961 0.33667440138819815 98 5.035965728052119 0.7513963814867208 0.2121739980267644 99 5.08197107124607 0.7514303536451561 0.2790245324945392 100 4.958076328919183 0.7536019748790875 0.2570090294100078
# Realizar "validação-cruzada manual" para encontrar a melhor divisão do modelo
for x in range(101):
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=x, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.696427433599541 0.7842515958041641 0.30339413261422876 1 4.717750596916709 0.7855469867762486 0.30144598744031303 2 4.695521563206421 0.7848396430488132 0.30605094815085077 3 4.705184304760873 0.784476525869226 0.3018106429107642 4 4.69959245921875 0.7846763868341616 0.30719446052510424 5 4.692925781198699 0.7827235120968024 0.3072701776861996 6 4.710843101680623 0.7884349692324375 0.3021646613554818 7 4.696242047520021 0.783745897545389 0.3064639021218081 8 4.709835192927134 0.7870679802872922 0.30050786463642487 9 4.706993658161434 0.7857011943661644 0.30450729312889824 10 4.704621765879621 0.7859838193063602 0.3036806068214999 11 4.718880342880114 0.7881867079066501 0.29959409735884346 12 4.700981528441687 0.7857107873114266 0.30366935349314395 13 4.7014953105140185 0.7849041482540662 0.30465687817024023 14 4.695911124888118 0.7839052241909101 0.30666890592165874 15 4.711065979976486 0.7846726065632 0.30140163629028527 16 4.712443450102636 0.7863794566736135 0.3015653791128047 17 4.707380101753842 0.7844150244480729 0.304328195310982 18 4.695783099345253 0.7858555801065329 0.3069605353520257 19 4.704104141446977 0.7858608968198759 0.30443177737519067 20 4.708101776523712 0.7839636846560644 0.302571961613175 21 4.701232812543046 0.7845299047856461 0.30077959082016736 22 4.709195801949819 0.7845827777373988 0.3047971307593518 23 4.715245275888775 0.7868514827418047 0.3006509546004038 24 4.702398348147799 0.7828948283701304 0.3020604094521029 25 4.702112632628592 0.7836669413780082 0.30326910363697956 26 4.703107007311202 0.784426361936169 0.30248769928017005 27 4.689797809149062 0.7836756923540924 0.30688752285011944 28 4.709618304591885 0.7858090242938107 0.30068766535707403 29 4.699966057230958 0.7846880841878329 0.30523908893691354 30 4.712356478724569 0.7876848116068205 0.3009617827785124 31 4.706513443786794 0.7851606550184639 0.3026137809095114 32 4.702572046863439 0.7853302210966142 0.3033762505981119 33 4.6961647810666065 0.7860922397927261 0.3054883794073474 34 4.711858182490299 0.7863744123850032 0.30383176321455685 35 4.707057101529408 0.7853767306076266 0.3038637018482031 36 4.705518367838273 0.7865848687374748 0.3039728195687289 37 4.715856735844087 0.7874688579397137 0.3026954702941962 38 4.70511243991849 0.7850748858668083 0.30320873243519697 39 4.701926148637086 0.7837942598124727 0.30444506579364927 40 4.699934183883274 0.7864576575479617 0.3060771102530976 41 4.702385560941364 0.7849429505834219 0.305392391686391 42 4.704395991258506 0.7823143661598321 0.3046197843174371 43 4.706657511305075 0.7855656000086597 0.3050041342650386 44 4.698049576283947 0.7844820014755334 0.3045520608989506 45 4.700458152641941 0.7845604416054137 0.3043364597920213 46 4.702946623380622 0.7828944058284856 0.3048979310023936 47 4.70243341391233 0.7830278589602654 0.3039838423939263 48 4.7088003369776175 0.7851099656980006 0.3044225140838026 49 4.701001473674256 0.7847134079110507 0.3047623117404118 50 4.690830523119689 0.7829091931875379 0.3071332938077497 51 4.697156693545133 0.7822534304236288 0.30644792859177894 52 4.696022854121656 0.781707974429964 0.3056519075965545 53 4.698155168989865 0.7842611012833106 0.3041178459820787 54 4.695584765308451 0.784076512229367 0.30746837001498684 55 4.707769456119942 0.7858810623197341 0.30239131595579105 56 4.708202289008231 0.7871391557162742 0.30455814312132334 57 4.701804514444104 0.7835182571303267 0.305362630065392 58 4.71157863776136 0.786428830036296 0.3020509560773752 59 4.702297894892006 0.7851270858399991 0.3046329692147599 60 4.697313321109963 0.7844245762816152 0.30432220064264837 61 4.694556585382489 0.7829097010638691 0.30716835767716943 62 4.692830251667412 0.7832897595060712 0.3069669052070758 63 4.7022233849380095 0.7851305407642009 0.3038616799056344 64 4.692595944842998 0.7843034295296023 0.30564719307057275 65 4.709274123090728 0.7858361372456788 0.30209273984929763 66 4.7025499188813225 0.7847595280071995 0.30308483209806125 67 4.705753382079654 0.785088941360231 0.3030964881193593 68 4.703523732046568 0.7856720727332784 0.30412550674580785 69 4.693032736040234 0.7832597457985329 0.3061774362513514 70 4.6971118791374815 0.783489579437095 0.3038179150425604 71 4.697145018282967 0.7825335520975247 0.30538655319472996 72 4.705081804774412 0.784667583040137 0.3027325808781367 73 4.715635419598174 0.7841162501173967 0.3023258565643504 74 4.703110194587642 0.7857762862583294 0.3045758763092359 75 4.700382844046672 0.7835467241940159 0.30380953298583846 76 4.698831306411146 0.7853349820059359 0.30642007277313477 77 4.712265160431539 0.7871740710863844 0.30152433497880704 78 4.705729064940952 0.7874934115887914 0.30454635778971917 79 4.704937273419492 0.7855998531491309 0.3026688765017741 80 4.712006777029967 0.7884052333697897 0.3035387528648974 81 4.712602680241844 0.7870837001013457 0.30266783833452415 82 4.711019493801388 0.7850444625984849 0.3039172847566036 83 4.708660398725646 0.7870099600596974 0.30264008831884737 84 4.700542120247951 0.7842787635662817 0.3024506942155737 85 4.708669936179954 0.7875712722961492 0.3024955147591504 86 4.702941469873002 0.7863953377277055 0.30409704904083945 87 4.706858007756426 0.7879359154492414 0.304210106028455 88 4.703858277461401 0.7836833730269078 0.30352601998380624 89 4.708174600414987 0.7866214543381288 0.3036666731129347 90 4.701329541930147 0.7841987284220393 0.3051454032708677 91 4.696202345146101 0.782401814729906 0.30492345608047566 92 4.704120298858664 0.7853163380843294 0.3042323782610198 93 4.694932556028168 0.7833901554326365 0.30552147597601476 94 4.709645281777534 0.7854578226449138 0.3028630801980293 95 4.712247769870338 0.7852710890954685 0.30211780177396996 96 4.721282721857906 0.7859179158456754 0.29885915976733135 97 4.7050771134171185 0.7844359683207459 0.3046671039480312 98 4.706667028405175 0.785239570735912 0.3040140407160876 99 4.7098332149661415 0.7833503832409556 0.30192500571249326 100 4.705894764239264 0.7848969121630311 0.3015681270696948
Não houve grande variação na performance, o modelo atingiu o "plateau" nesses dados.
Ajustes futuros caso necessário:
- Remoção de Outliers (valores discrepantes)
- Préprocessar/Escalonar/Normalizar/OHE nos dados
- Engenharia de Atributos (novos dados com base nos atuais)
df.head()
| trimestre | mes | semana | dia | dia_semana | horas | quantidade | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 1 | 1 | 3 | 11 | 6 |
| 1 | 1 | 1 | 1 | 1 | 3 | 12 | 17 |
| 2 | 1 | 1 | 1 | 1 | 3 | 13 | 33 |
| 3 | 1 | 1 | 1 | 1 | 3 | 14 | 15 |
| 4 | 1 | 1 | 1 | 1 | 3 | 15 | 14 |
# Detecção de outliers
# Criar uma figura e os eixos para os subplots
fig, axs = plt.subplots(1, 2, figsize=(12, 6))
# Boxplot
sns.boxplot(data=df, y='quantidade', ax=axs[0])
axs[0].set_title('Boxplot da Quantidade de Pizzas')
# Violinplot
sns.violinplot(data=df, y='quantidade', ax=axs[1])
axs[1].set_title('Violinplot da Quantidade de Pizzas')
# Ajustar o layout
plt.tight_layout()
# Mostrar os subplots
plt.show()
Abordagem 1: Z-Score
O Z-Score é uma medida estatística que indica o quão longe um ponto de dados está da média em termos de desvios padrão. Geralmente, consideramos pontos de dados com um Z-Score acima de 3 (ou abaixo de -3) como outliers.
Abordagem 2: Intervalo Interquartil (IQR)
O intervalo interquartil é uma medida estatística que calcula a diferença entre o primeiro quartil (Q1) e o terceiro quartil (Q3). Geralmente, consideramos pontos de dados abaixo de Q1 - 1,5 * IQR ou acima de Q3 + 1,5 * IQR como outliers.
Abordagem 3: Visualização Boxplot O boxplot é uma visualização gráfica que mostra a distribuição dos dados e identifica os valores discrepantes (outliers).
from scipy import stats
# Calcular o Z-Score para a coluna 'quantidade'
z_scores = stats.zscore(df['quantidade'])
# Identificar outliers com Z-Score acima de 3 ou abaixo de -3
outliers_zscore = df[(z_scores > 3) | (z_scores < -3)]
print("Outliers detectados usando Z-Score:")
print(outliers_zscore)
Outliers detectados usando Z-Score:
trimestre mes semana dia dia_semana horas quantidade
19 1 1 1 2 4 18 36
84 1 1 2 8 3 12 49
209 1 1 4 19 0 12 43
221 1 1 4 20 1 12 43
326 1 1 5 29 3 13 39
384 1 2 6 3 1 12 47
420 1 2 6 6 4 13 37
583 1 2 8 20 4 13 38
644 1 2 9 25 2 12 37
655 1 2 9 26 3 13 38
714 1 3 10 3 1 13 36
736 1 3 10 5 3 13 39
746 1 3 10 6 4 12 40
1037 1 3 14 31 1 13 37
1060 2 4 14 2 3 12 37
1202 2 4 16 14 1 12 43
1238 2 4 16 17 4 12 41
1273 2 4 17 20 0 12 40
1389 2 4 18 30 3 13 42
1393 2 4 18 30 3 17 41
1483 2 5 19 8 4 12 43
1609 2 5 21 19 1 12 39
1727 2 5 22 29 4 13 38
1761 2 6 23 1 0 12 46
1795 2 6 23 4 3 12 49
1866 2 6 24 10 2 12 41
2073 2 6 26 27 5 18 36
2388 3 7 30 24 4 18 36
2420 3 7 31 27 0 13 39
2452 3 7 31 30 3 13 48
2544 3 8 32 7 4 12 37
2626 3 8 33 14 4 13 44
2780 3 8 35 27 3 12 39
2875 3 9 36 4 4 12 36
3040 3 9 38 18 4 13 39
3165 4 10 40 1 3 12 45
3309 4 10 42 15 3 13 64
3313 4 10 42 15 3 17 40
3364 4 10 43 21 2 13 36
3400 4 10 43 24 5 13 40
3460 4 10 44 30 4 12 43
3495 4 11 45 2 0 12 39
3577 4 11 46 9 0 13 42
3658 4 11 47 16 0 12 36
3681 4 11 47 18 2 12 46
3774 4 11 48 26 3 12 40
3780 4 11 48 26 3 18 39
3781 4 11 48 26 3 19 42
3786 4 11 48 27 4 12 36
3985 4 12 51 14 0 12 47
4057 4 12 51 20 6 13 40
4136 4 12 53 28 0 12 36
# Calcular o intervalo interquartil (IQR)
Q1 = df['quantidade'].quantile(0.25)
Q3 = df['quantidade'].quantile(0.75)
IQR = Q3 - Q1
# Identificar outliers usando o IQR
outliers_iqr = df[(df['quantidade'] < Q1 - 1.5 * IQR) | (df['quantidade'] > Q3 + 1.5 * IQR)]
print("Outliers detectados usando IQR:")
print(outliers_iqr)
Outliers detectados usando IQR:
trimestre mes semana dia dia_semana horas quantidade
2 1 1 1 1 3 13 33
13 1 1 1 2 4 12 32
19 1 1 1 2 4 18 36
84 1 1 2 8 3 12 49
151 1 1 3 14 2 12 34
... ... ... ... ... ... ... ...
4009 4 12 51 16 2 13 33
4037 4 12 51 18 4 18 32
4057 4 12 51 20 6 13 40
4136 4 12 53 28 0 12 36
4149 4 12 53 29 1 13 33
[98 rows x 7 columns]
# Remover outliers (36 ou mais)
df = df.loc[df['quantidade'] <= 35]
df.shape
(4129, 7)
- MAE Modelo: 4.696427433599541
- MAPE Modelo: 0.7842515958041641
- R2 Modelo: 0.30339413261422876
X = df.drop('quantidade', axis=1)
y = df['quantidade']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(f'MAE Modelo: {mae_model}')
print(f'MAPE Modelo: {mape_model}')
print(f'R2 Modelo: {r2_model}')
# Visualizar valores reais, média e previsões
plt.plot(np.arange(len(y_test)), y_test, label='Valor Real', alpha=0.5)
plt.plot(np.arange(len(y_test)), y_pred, label='Previsão', alpha=0.5)
plt.legend();
MAE Modelo: 4.933904628966974 MAPE Modelo: 0.8431398397132617 R2 Modelo: 0.23383317583829355
# Ajuste e tunagem de hiperparâmetros do modelo para melhorar a performance
from sklearn.model_selection import GridSearchCV
# Definindo os hiperparâmetros que gostaríamos de sintonizar
param_grid = {
'n_estimators': [50, 100, 200, 300],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# Criando o modelo RandomForestRegressor
rf = RandomForestRegressor(random_state=42)
# Criando um objeto GridSearchCV
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2)
# Ajustando o modelo aos dados de treinamento
grid_search.fit(X_train, y_train)
# Obtendo o melhor modelo
best_rf = grid_search.best_estimator_
# Avaliando o modelo nos dados de teste
test_score = best_rf.score(X_test, y_test)
print("Melhores hiperparâmetros encontrados:", grid_search.best_params_)
print("Desempenho do modelo nos dados de teste:", test_score)
Fitting 5 folds for each of 108 candidates, totalling 540 fits
Melhores hiperparâmetros encontrados: {'max_depth': 10, 'min_samples_leaf': 4, 'min_samples_split': 10, 'n_estimators': 300}
Desempenho do modelo nos dados de teste: 0.2298059790138589
# Realizar "validação-cruzada manual" para encontrar a melhor divisão de treino/teste
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=x, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.933904628966974 0.8431398397132617 0.23383317583829355 1 4.830479643729925 0.6793876574096307 0.24516007222142433 2 4.760641233251215 0.7326978892690229 0.27809625403775395 3 4.955420735757988 0.7828904265250688 0.25761402163360403 4 4.620597683169491 0.7793286887399556 0.25786140504290256 5 4.930490292688042 0.7787495334017024 0.27903621341386176 6 4.869143583433105 0.7050169622508877 0.2611453447475829 7 4.765110553557504 0.7517532940108638 0.2758275454919068 8 4.548767909493937 0.6552338601550838 0.2839289247489337 9 4.933696173288352 0.8030788686535528 0.21559243806192607 10 4.819948334687458 0.8204831518094899 0.2863703514232512 11 4.85209662028169 0.7821335144479705 0.26611208167525624 12 4.893372149793256 0.7842867953895148 0.23518795964039196 13 4.847110040612151 0.8016140557638868 0.2906276514008903 14 4.462746091693319 0.6777815259554479 0.251316952373164 15 4.536403543637066 0.7445286345209234 0.2777030539148968 16 4.810399361095445 0.7924676062980767 0.2804534698757918 17 4.750114630605542 0.6599601162834381 0.2750013909320431 18 4.67577627738819 0.8213632286335478 0.2667990137574271 19 4.5991539368969425 0.7513643895323356 0.3066591128806476 20 4.718677948004971 0.754842710747496 0.2934115402313433 21 4.595043387649349 0.796501107847716 0.3311085644148285 22 4.841681696079033 0.8058304377010949 0.22736524364568134 23 4.855540274357885 0.7114319156935001 0.21344614537349993 24 4.934496782026977 0.7553740288108998 0.2948538689389304 25 4.898272267181943 0.7636807074690765 0.2932022052789972 26 4.779464881369831 0.7325042517787239 0.2661610349440682 27 4.805693081024227 0.8385851075301777 0.298032919960199 28 4.703411760626255 0.7924815607085073 0.25135124844130974 29 4.618222348752155 0.711237904701784 0.2834149054035522 30 4.787642110180113 0.8196672137603532 0.2685351491253867 31 4.822032887427978 0.7826976704845603 0.2756425853069152 32 4.620615848904814 0.7556344471684885 0.24907606836907903 33 4.716438608282815 0.7994147281027908 0.30641991731801244 34 4.5495472692245364 0.699320432293502 0.31492337096681877 35 4.905227842941547 0.7642151428415342 0.2779510444933945 36 4.5989049627220515 0.7536282180840823 0.31280158518101253 37 4.649902287087326 0.786195105812898 0.2789911853309096 38 4.739449830516299 0.7888276772667215 0.28231221957260844 39 4.910539446022572 0.7341734510963017 0.24840154216536015 40 4.8571146725308685 0.7714315869146638 0.26822291522407093 41 4.839722956995777 0.7917857726597617 0.28758498736034543 42 4.699175146701875 0.7670238146461288 0.29996472758266735 43 4.671741624193953 0.740813230422204 0.22838566461599275 44 4.731464524152063 0.7565746248630598 0.2681910677399979 45 4.56551149758176 0.6875888816800291 0.2773893076707862 46 4.772137129227717 0.735564739089248 0.238329745425513 47 4.64297730171861 0.7798012348074221 0.3281293570054271 48 4.9218361785621925 0.7088413414125323 0.2547043367502583 49 4.687724344427326 0.7226057322447733 0.30182441270630755 50 4.558730613818513 0.7431516556078591 0.24814723991067078 51 4.711244138674169 0.8140967847024027 0.2951360077861632 52 4.640559862806105 0.7433855342412728 0.2969314727672261 53 4.825195156918919 0.6993908461003921 0.24105580930534254 54 4.883057961238591 0.8401971287684058 0.21675969862368327 55 4.869722046889359 0.7698472987185709 0.24649442064935756 56 4.807495885230472 0.7796696993399672 0.24202274119491818 57 4.921051709965807 0.8219224011309996 0.2593764589324804 58 4.691624375713898 0.7823240635032631 0.2575054586556973 59 4.42827639876734 0.7426326825066043 0.3199507397843613 60 4.81598986374824 0.8028053275066466 0.28481304425267684 61 4.7928381137667015 0.719674687113551 0.298237247548215 62 4.64856243652905 0.7563884836148023 0.29094456960958914 63 4.729490801451929 0.8691316273037601 0.28767648579198524 64 4.7768911297680505 0.757377543497489 0.2533086480682467 65 4.813315777549224 0.7537781659605064 0.3153757267480476 66 4.672093029937383 0.7246054425363188 0.27692319624680395 67 4.850018159509281 0.727775733301209 0.27181139639963503 68 4.533838151807849 0.7402379768854263 0.27925994887329686 69 4.843762307456189 0.8186669245755152 0.2531528056109912 70 4.950213996435625 0.7516984341361181 0.19911173929406967 71 4.747771014319114 0.7931072792415983 0.3023470079851702 72 4.846081690961059 0.778100564613803 0.24042460259985843 73 4.71367983838704 0.7532099296305446 0.23719258328372483 74 4.868993985252532 0.7724859731275181 0.2628514743668582 75 4.66237729805905 0.6778594124921195 0.2730298805558098 76 4.759732432955659 0.76270104525677 0.30474978247958373 77 4.826615510374213 0.7397114070337506 0.232441830610994 78 4.8801157060808915 0.7433236209310052 0.2284929886825925 79 4.75628875750527 0.7476644282408228 0.2764415628240606 80 4.6849087773112705 0.7885633329080108 0.25475790475874616 81 4.831358882352914 0.7416132463435817 0.2823709042715278 82 4.8553468134291045 0.7419370858073224 0.253392419347924 83 4.5753757044124255 0.7658275572927522 0.2576271820733076 84 4.801616385247858 0.8068658948023595 0.25870884508125414 85 4.881716276567635 0.7273170128595282 0.2901263682687262 86 4.864694234301492 0.7912886824053479 0.26296451814060173 87 4.697816180507248 0.7131404593327666 0.2717163356976998 88 4.938298725399797 0.792599989157251 0.24711231532476763 89 4.8723891633940655 0.8031283885964036 0.2589567082239328 90 4.813190442187303 0.7461243843697116 0.22865161197238404 91 4.739615399788486 0.7951152972212867 0.2534248862943469 92 4.827084440533346 0.790670572871477 0.29671554326583327 93 4.855065858099362 0.8059104145458246 0.31534586209496185 94 4.561441104020651 0.8512120045112964 0.29804750879055697 95 4.643543879386131 0.6728417449932586 0.27327035153925394 96 4.711647111844288 0.8115197270981774 0.26096480847247217 97 4.591808818054816 0.7483718126562471 0.2962752479534687 98 4.831277146958077 0.7834909282405115 0.2805939994359924 99 4.733797446807593 0.7358053650613082 0.24833301331344437 100 4.521377565542844 0.731080188171933 0.3243432115745989
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
print(f'MAE Modelo: {mae_model}')
print(f'MAPE Modelo: {mape_model}')
# Visualizar valores reais, média e previsões
plt.plot(np.arange(len(y_test)), y_test, label='Valor Real', alpha=1)
plt.plot(np.arange(len(y_test)), y_pred, label='Previsão', alpha=1)
plt.legend();
MAE Modelo: 4.462746091693319 MAPE Modelo: 0.6777815259554479
# Encontrar as melhores variáveis para o modelo
# Extrair a importância das features
importancias = model.feature_importances_
# Criar um DataFrame com as importâncias das features
importancias_df = pd.DataFrame({'Feature': X.columns, 'Importância': importancias})
# Ordenar as features pela importância
importancias_df = importancias_df.sort_values(by='Importância', ascending=False)
# Exibir as melhores variáveis
print("Melhores variáveis para o modelo RandomForestRegressor:")
print(importancias_df)
Melhores variáveis para o modelo RandomForestRegressor:
Feature Importância
5 horas 0.52
4 dia_semana 0.18
3 dia 0.14
2 semana 0.12
1 mes 0.03
0 trimestre 0.01
# Remover variáveis com pouca importância para o modelo
df.drop(['mes', 'trimestre'], axis=1, inplace=True)
df.head()
| semana | dia | dia_semana | horas | quantidade | |
|---|---|---|---|---|---|
| 0 | 1 | 1 | 3 | 11 | 6 |
| 1 | 1 | 1 | 3 | 12 | 17 |
| 2 | 1 | 1 | 3 | 13 | 33 |
| 3 | 1 | 1 | 3 | 14 | 15 |
| 4 | 1 | 1 | 3 | 15 | 14 |
X = df.drop('quantidade', axis=1)
y = df['quantidade']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
print(f'MAE Modelo: {mae_model}')
print(f'MAPE Modelo: {mape_model}')
# Visualizar valores reais, média e previsões
plt.plot(np.arange(len(y_test)), y_test, label='Valor Real', alpha=1)
plt.plot(np.arange(len(y_test)), y_pred, label='Previsão', alpha=1)
plt.legend();
MAE Modelo: 4.463512847251722 MAPE Modelo: 0.6775700073326069
# Realizar "validação-cruzada manual" para encontrar a melhor divisão de treino/teste
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=x, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.933324086755492 0.8431725301016347 0.23384150279411642 1 4.828944396550863 0.6792489041618217 0.24606864868241374 2 4.7599914855166 0.7319003947597537 0.2781831253166849 3 4.956412931049722 0.7828273661683675 0.2574038752451885 4 4.6196195474877175 0.7789068024019775 0.2577585187446212 5 4.929680455809618 0.778604151054264 0.2793044902711286 6 4.86778306534222 0.7045495466494327 0.2612108726409119 7 4.762855842268671 0.7513404198295893 0.2763633926123853 8 4.549610164378796 0.6558419036882523 0.28416952485900815 9 4.932214304585133 0.8027536452578943 0.21593251066263386 10 4.819658211920759 0.8212734406104077 0.28594280306808895 11 4.850663392120978 0.7817560207607177 0.2664102209790449 12 4.891206837603604 0.7830900620521672 0.23573259086101195 13 4.846647413109653 0.8014653311678684 0.29059615764663294 14 4.463512847251722 0.6775700073326069 0.2512593512012141 15 4.535089855988175 0.7448522609334802 0.27797541251181535 16 4.810288150581968 0.7925513785042579 0.2807686024460845 17 4.751058137649137 0.660215595889354 0.2745938011173402 18 4.675299335135894 0.8212564128894823 0.26706161349107693 19 4.597386964891892 0.7512965376215192 0.30702822924796147 20 4.721067259587776 0.7553717933115145 0.292868003347589 21 4.59407324044616 0.7961262280234361 0.33135840171714315 22 4.840420487149538 0.8054954273886813 0.2276909134161541 23 4.854524727876926 0.7115370825238468 0.2135747172961664 24 4.9325315967787615 0.7551438476707477 0.29524673705555915 25 4.897802465489488 0.7636564677963629 0.29344331550117697 26 4.779646360634199 0.7325691116062607 0.26619822231284196 27 4.803331214212652 0.8379917176161279 0.29836093834183297 28 4.69847093091039 0.7917169347023666 0.25209577415862905 29 4.619209184525435 0.7114768240828576 0.2834750179072566 30 4.788540015788243 0.8198394816296569 0.26838869249764374 31 4.821681679247793 0.7825553683436992 0.27593369855529504 32 4.620121011877979 0.755217271057347 0.24947503779023172 33 4.714720927335457 0.7989394723910515 0.30674191511429105 34 4.549038349701296 0.6993284190771341 0.31517318498180635 35 4.9030718373932 0.7640756174066126 0.27805420797319713 36 4.595898241861417 0.7527398262376772 0.3135654728523579 37 4.651135963025205 0.7868393354633992 0.27869462338530704 38 4.73667001980204 0.7882470922372612 0.28265122513915475 39 4.911381587121802 0.7343788812581721 0.24848599901305035 40 4.855779454782581 0.7715191784873117 0.2692315084239283 41 4.839833317269426 0.7917319712144671 0.287819253624813 42 4.698824279073668 0.7661195745318331 0.30030089103908564 43 4.672568165304454 0.7410831047823583 0.22826512949370392 44 4.732938052314943 0.7563482217469846 0.267851216353425 45 4.565895278128659 0.6874999973521332 0.27732828309324087 46 4.773222021264309 0.7355981110030183 0.23806648880039039 47 4.641742505502161 0.7798153104982599 0.328341507305554 48 4.922812372324775 0.7090513295503429 0.25466996339910075 49 4.685420678611697 0.7223082571752298 0.3020645964157561 50 4.557644660266437 0.742189130977009 0.24842940363542654 51 4.711818804071764 0.8143180091106438 0.2950107996441902 52 4.641472807831193 0.7435986018516426 0.29672377513330006 53 4.824668479656078 0.6994774285908039 0.24086227134094162 54 4.881710029496793 0.8398397905153675 0.21693249244880608 55 4.8701234334059595 0.7697242722699977 0.24639252239290432 56 4.808596911716022 0.7799416467791803 0.24179561876157174 57 4.921883878015204 0.8218305606878445 0.25958637074037216 58 4.690369722762319 0.7819387547661649 0.25798094557532547 59 4.427386105787714 0.7432118682305523 0.320331387861992 60 4.815044862541973 0.8022095045021762 0.28493157443083006 61 4.792781698674565 0.7194068549887918 0.29842254013935743 62 4.648844258886766 0.7559563791882481 0.2907683086370738 63 4.73068779869236 0.8689760754255846 0.2874062257680644 64 4.774624336720062 0.756858797980468 0.25369857635385307 65 4.811857050209025 0.7537584679218653 0.315444164054562 66 4.671626495155192 0.724096198551694 0.27713046863423796 67 4.85042294340932 0.7279108387341501 0.27165206221199856 68 4.530972770402811 0.7392895839542488 0.28003064379382414 69 4.844738686128135 0.8185349699739076 0.2530446558963988 70 4.945772073392219 0.7512377434146564 0.19993673763499886 71 4.7476587384170585 0.7933153131762611 0.3023763543477752 72 4.846177313455588 0.7784096589738839 0.2404420151220661 73 4.712627305433429 0.7525414548528179 0.23769721384709885 74 4.865797018110932 0.772150131531609 0.26341623646669365 75 4.662881734493607 0.677730472195785 0.2732450218951451 76 4.759287235214426 0.7628363463995484 0.3045287390217807 77 4.8272186777880215 0.739518983594918 0.23235777806230884 78 4.878118607185863 0.7427516558733402 0.22939271189843957 79 4.754449208651227 0.7474129174196555 0.27661612476607655 80 4.684970856817501 0.788157289193612 0.2547332202133592 81 4.8298417133839795 0.7410511179502387 0.28288295338346836 82 4.853845834510612 0.7412965213012483 0.25321367044140064 83 4.5766579271425325 0.765175074677101 0.2572285341494148 84 4.804071061688877 0.8079778606072627 0.2583780563558634 85 4.8796926253170545 0.7264026535910639 0.29080710817040334 86 4.866241723658758 0.7921300385506772 0.26256282716560553 87 4.697056192482417 0.7130444407586075 0.2717769550100583 88 4.937922019383599 0.7925394379611278 0.2474180046479696 89 4.873804463183972 0.8031481242454099 0.2586892436933299 90 4.812360547366434 0.7461605042457209 0.22873011714159364 91 4.739342738369208 0.7949208568872942 0.25343176887135443 92 4.823739243603774 0.7900749460532432 0.29732945328811733 93 4.8538276846579755 0.8053624218557212 0.3153237749307851 94 4.562055931498944 0.8512031570164859 0.29816056914606304 95 4.644718226883466 0.6730893076047374 0.2730064313166565 96 4.711945077800171 0.8121108567343834 0.2608592859642621 97 4.590846428286923 0.7485273542101071 0.29626077849539323 98 4.829664909231142 0.7827372514492481 0.28100162090924485 99 4.735709462693023 0.7359903390120471 0.24791468615170276 100 4.519389557897503 0.73047507655188 0.32483884373876626
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14, test_size=0.2)
# Definindo os hiperparâmetros que gostaríamos de sintonizar
param_grid = {
'n_estimators': [50, 100, 200, 300],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# Criando o modelo RandomForestRegressor
rf = RandomForestRegressor(random_state=42)
# Criando um objeto GridSearchCV
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2)
# Ajustando o modelo aos dados de treinamento
grid_search.fit(X_train, y_train)
# Obtendo o melhor modelo
best_rf = grid_search.best_estimator_
# Avaliando o modelo nos dados de teste
test_score = best_rf.score(X_test, y_test)
print("Melhores hiperparâmetros encontrados:", grid_search.best_params_)
print("Desempenho do modelo nos dados de teste:", test_score)
Fitting 5 folds for each of 108 candidates, totalling 540 fits
Melhores hiperparâmetros encontrados: {'max_depth': 10, 'min_samples_leaf': 4, 'min_samples_split': 10, 'n_estimators': 300}
Desempenho do modelo nos dados de teste: 0.2470986336234544
X = df.drop('quantidade', axis=1)
y = df['quantidade']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
print(f'MAE Modelo: {mae_model}')
print(f'MAPE Modelo: {mape_model}')
# Visualizar valores reais, média e previsões
plt.plot(np.arange(len(y_test)), y_test, label='Valor Real', alpha=1)
plt.plot(np.arange(len(y_test)), y_pred, label='Previsão', alpha=1)
plt.legend();
MAE Modelo: 4.463512847251722 MAPE Modelo: 0.6775700073326069
df.head()
| semana | dia | dia_semana | horas | quantidade | |
|---|---|---|---|---|---|
| 0 | 1 | 1 | 3 | 11 | 6 |
| 1 | 1 | 1 | 3 | 12 | 17 |
| 2 | 1 | 1 | 3 | 13 | 33 |
| 3 | 1 | 1 | 3 | 14 | 15 |
| 4 | 1 | 1 | 3 | 15 | 14 |
df.groupby('horas')[['quantidade']].sum()
| quantidade | |
|---|---|
| horas | |
| 9 | 4 |
| 10 | 18 |
| 11 | 2728 |
| 12 | 5658 |
| 13 | 5677 |
| 14 | 3613 |
| 15 | 3216 |
| 16 | 4239 |
| 17 | 5130 |
| 18 | 5270 |
| 19 | 4364 |
| 20 | 3534 |
| 21 | 2545 |
| 22 | 1386 |
| 23 | 68 |
# Remover horas outliers (9, 10, 23)
df = df.loc[df['horas'] != 9]
df = df.loc[df['horas'] != 10]
df = df.loc[df['horas'] != 23]
df.shape
(4094, 5)
df.groupby('dia_semana')[['quantidade']].sum()
| quantidade | |
|---|---|
| dia_semana | |
| 0 | 6110 |
| 1 | 6646 |
| 2 | 6781 |
| 3 | 6779 |
| 4 | 7672 |
| 5 | 7383 |
| 6 | 5989 |
# 1 para dia_semana = 4 ou 5 (sexta ou sábado) e 0 para demais dias
# Criar a nova coluna "dia_pico" com base na condição especificada
df['dia_pico'] = df['dia_semana'].apply(lambda x: 1 if x in [4, 5] else 0)
# "hora_pico" com 2 para hora = 12, 13, 17 ou 18; 1 para hora = 14, 15, 19 ou 20 e 0 para as demais
# Lista de horas consideradas como pico
horas_pico_2 = [12, 13, 17, 18]
horas_pico_1 = [14, 15, 19, 20]
# Função para atribuir valores à nova coluna com base na hora
def atribuir_valor(hora):
if hora in horas_pico_2:
return 2
elif hora in horas_pico_1:
return 1
else:
return 0
# Criar a nova coluna "hora_pico" com base na condição especificada
df['hora_pico'] = df['horas'].apply(atribuir_valor)
df.head()
| semana | dia | dia_semana | horas | quantidade | dia_pico | hora_pico | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 3 | 11 | 6 | 0 | 0 |
| 1 | 1 | 1 | 3 | 12 | 17 | 0 | 2 |
| 2 | 1 | 1 | 3 | 13 | 33 | 0 | 2 |
| 3 | 1 | 1 | 3 | 14 | 15 | 0 | 1 |
| 4 | 1 | 1 | 3 | 15 | 14 | 0 | 1 |
X = df.drop('quantidade', axis=1)
y = df['quantidade']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
print(f'MAE Modelo: {mae_model}')
print(f'MAPE Modelo: {mape_model}')
# Visualizar valores reais, média e previsões
plt.plot(np.arange(len(y_test)), y_test, label='Valor Real', alpha=1)
plt.plot(np.arange(len(y_test)), y_pred, label='Previsão', alpha=1)
plt.legend();
MAE Modelo: 4.667365853452154 MAPE Modelo: 0.854480815290271
# Realizar "validação-cruzada manual" para encontrar a melhor divisão de treino/teste
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=x, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=300, min_samples_leaf=4,
min_samples_split=10, max_depth=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.853180100064876 0.7648956830647401 0.21592663704270343 1 4.620160907647249 0.7171703096994798 0.30238431174508484 2 4.782357487356142 0.6840461960006737 0.28187178642033894 3 4.900935606032827 0.7617376111633702 0.23359514986196994 4 4.685542448809243 0.7991374967749786 0.2668660043029255 5 4.879684613244206 0.7127625262694637 0.2546688271833667 6 4.8959748455766166 0.8013467445385187 0.27588717511984295 7 4.808272026112922 0.7756584084310665 0.28227744990723613 8 4.660737887982036 0.7171408891437946 0.2551586613817901 9 4.7528472142960565 0.6700002586599384 0.2792806879891647 10 4.882055659987442 0.7295880441148432 0.2380146509795129 11 4.809877810871126 0.7723638445219909 0.257786064797464 12 4.8627451531723205 0.726736658568209 0.2686619828649136 13 4.728152537415341 0.7054055299716349 0.22051681031672032 14 4.667365853452154 0.854480815290271 0.26881198328527955 15 5.090497512718426 0.8192037779926225 0.2366376131945911 16 4.8380932130485395 0.7880485805989642 0.22333789024821538 17 4.810355273167798 0.8048954127501371 0.2674468186794128 18 4.560823759907347 0.7369952685090556 0.23507584596921738 19 4.8308898634838995 0.7074804588990522 0.23146799088784564 20 4.888408203547573 0.7740130894598267 0.2357786043790867 21 4.631372378615471 0.7697046828327646 0.2770552560553937 22 4.836887470547207 0.7793904175033869 0.2709490339518944 23 4.809782014604811 0.7771893851028752 0.2746491848799689 24 4.682306829707318 0.6678535880963504 0.2332273763171553 25 4.844288407238963 0.7468377975573111 0.2716907666514732 26 4.715806418485972 0.7356655838270506 0.2725159690803285 27 5.049767737218666 0.8209358692997987 0.23775429788618196 28 4.9681247797757315 0.7581256166693615 0.22187363008941485 29 5.13266736360893 0.8152058253825483 0.24030243872283752 30 4.694885879236714 0.7330904966616661 0.27416330702250724 31 4.74610279289636 0.8109466350564316 0.30603922735724554 32 4.897148587081857 0.7397090244839634 0.2503807424803772 33 4.693694894153408 0.7174444385889338 0.2680072098115096 34 4.699501854019414 0.7060141359663176 0.29357561165523216 35 4.901524482118887 0.778821423501011 0.24960812007575983 36 4.965220426430936 0.8286431120020348 0.19306597228720357 37 4.804801788923605 0.7632004506124541 0.2184229796773971 38 4.712451078916617 0.6980223381508911 0.2715590354660702 39 4.598604229168111 0.8250150420704792 0.3132635171123216 40 5.00362121437225 0.8367165918003872 0.24348295044839008 41 4.9421204232810885 0.7800267513019362 0.2884697219094542 42 4.825914843315717 0.8394931169170101 0.24691349954886332 43 4.908170028378944 0.7477108801445157 0.3227349276977868 44 4.7426041722831975 0.8482597400132689 0.24208362519690996 45 4.982096894783548 0.748564244620986 0.26827791206747165 46 4.75491047686033 0.7807187402571971 0.2584214392285863 47 4.795930451742139 0.7611042325981944 0.251973956674329 48 4.722726139094047 0.7665753393007724 0.1899813147187046 49 4.523246698929944 0.7079307209136099 0.2706615320323402 50 4.853244820775553 0.7856427916147085 0.2703056584206984 51 4.788882506953534 0.6982392310393978 0.24081275995088902 52 4.639014597011517 0.6992627795572622 0.31066514720207883 53 4.738910417872879 0.7247778842830152 0.25227421584497445 54 4.722567526236534 0.6932174025656683 0.2779512700090453 55 4.836186105836303 0.7515025538093313 0.2532861677195586 56 4.687582738203526 0.7921573876253626 0.2725593762214631 57 4.649993501203417 0.7335419468819707 0.2802142658470008 58 4.5022595528375655 0.6694333676940049 0.25934993953503294 59 5.07712756428258 0.7424103837595079 0.24075045557370955 60 4.754448106092589 0.7778269820060794 0.23742530223397107 61 4.983542097182451 0.7607225712763205 0.2809577580183068 62 4.754679739973179 0.7558990927291164 0.25295533324902886 63 4.855391947739696 0.7913318909005245 0.2309924260960321 64 4.928550918576095 0.7654838313578035 0.22944799740144994 65 4.625699887494401 0.6174817885050045 0.23999784634314925 66 4.778941308253297 0.7656051370601988 0.26037950565277146 67 4.81109821856753 0.7916028697204244 0.24361316882240658 68 4.645697925224764 0.6798716046136043 0.25310670992539797 69 4.6025412049777215 0.7852165354302488 0.2800055718485396 70 4.763315153824904 0.7435153452125322 0.269092749440776 71 4.740339762060465 0.6915712045536067 0.2343325680580084 72 4.692519644872348 0.6987689274800116 0.3236955730650324 73 4.821554661818182 0.6984002294494007 0.3004917315509029 74 4.686696767275093 0.7780128102624386 0.3165654493869605 75 4.741577405415953 0.6975600421232367 0.29860695816293037 76 4.717312229673855 0.7164459744040351 0.2503119879636475 77 4.650925124845636 0.7945389097118829 0.314856195167034 78 4.851170808313512 0.764390379329723 0.2227704380316866 79 4.966115632560336 0.7988225095811371 0.24272696914950365 80 4.763187950738955 0.7617041638507417 0.2647054875717828 81 4.774580208487345 0.7264914873510921 0.21292754793542357 82 4.800193145655878 0.6774093427996964 0.2666257529555607 83 4.703861382968545 0.7093975670245634 0.2847877341960986 84 4.732923632431662 0.7172383884314759 0.27085942413526554 85 4.8666295968609505 0.7718568242347447 0.24094465367432738 86 4.614707143200588 0.7777419820025148 0.3146637473737711 87 4.9240387564608055 0.792639662175441 0.22583670077101192 88 4.707363785551441 0.6405626871041912 0.2704286494837307 89 4.79790775835083 0.8229752928517632 0.29086646669099847 90 4.7647074265596965 0.6582318223304422 0.2478425078024179 91 5.056840560336151 0.8334170143352729 0.1994111450206102 92 4.677575405486605 0.7843611655344029 0.2701824226195845 93 4.899465377876377 0.7647815639068807 0.2734184595772091 94 4.622480941332917 0.7048128480929208 0.2917300420095661 95 4.862581116016496 0.7471146645092636 0.2379033810597191 96 4.573322052135349 0.6960002142520291 0.2582192844171477 97 4.802243855877825 0.8056388549453694 0.2568766564796936 98 4.911085958038389 0.6747117763414541 0.2794572723757247 99 4.679882443534216 0.791647159020572 0.28699311652498527 100 4.817788754748623 0.7859629565606328 0.2905554863904223
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14, test_size=0.2)
# Definindo os hiperparâmetros que gostaríamos de sintonizar
param_grid = {
'n_estimators': [50, 100, 200, 300],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# Criando o modelo RandomForestRegressor
rf = RandomForestRegressor(random_state=42)
# Criando um objeto GridSearchCV
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2)
# Ajustando o modelo aos dados de treinamento
grid_search.fit(X_train, y_train)
# Obtendo o melhor modelo
best_rf = grid_search.best_estimator_
# Avaliando o modelo nos dados de teste
test_score = best_rf.score(X_test, y_test)
print("Melhores hiperparâmetros encontrados:", grid_search.best_params_)
print("Desempenho do modelo nos dados de teste:", test_score)
Fitting 5 folds for each of 108 candidates, totalling 540 fits
Melhores hiperparâmetros encontrados: {'max_depth': 10, 'min_samples_leaf': 4, 'min_samples_split': 10, 'n_estimators': 200}
Desempenho do modelo nos dados de teste: 0.26294896400916423
# Definindo os hiperparâmetros que gostaríamos de sintonizar
param_grid = {
'n_estimators': [150, 175, 200, 225],
'max_depth': [8, 10, 12],
'min_samples_split': [8, 10, 12],
'min_samples_leaf': [4, 5, 6]
}
# Criando o modelo RandomForestRegressor
rf = RandomForestRegressor(random_state=42)
# Criando um objeto GridSearchCV
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2)
# Ajustando o modelo aos dados de treinamento
grid_search.fit(X_train, y_train)
# Obtendo o melhor modelo
best_rf = grid_search.best_estimator_
# Avaliando o modelo nos dados de teste
test_score = best_rf.score(X_test, y_test)
print("Melhores hiperparâmetros encontrados:", grid_search.best_params_)
print("Desempenho do modelo nos dados de teste:", test_score)
Fitting 5 folds for each of 108 candidates, totalling 540 fits
Melhores hiperparâmetros encontrados: {'max_depth': 8, 'min_samples_leaf': 6, 'min_samples_split': 8, 'n_estimators': 200}
Desempenho do modelo nos dados de teste: 0.2828578307227386
# Realizar "validação-cruzada manual" para encontrar a melhor divisão de treino/teste
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=x, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=0, n_estimators=200, min_samples_leaf=6,
min_samples_split=8, max_depth=8)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.794722350915415 0.7578336240656258 0.23762037615156162 1 4.560100504479704 0.7143453228294474 0.32488481331561725 2 4.747045258991163 0.6836453504451606 0.29350707383436436 3 4.811845193141866 0.7527855598347092 0.2558065495745535 4 4.606634765791028 0.7901700244664387 0.29070207854290553 5 4.8100524405114475 0.710636643458985 0.27611695948219916 6 4.838010403184417 0.7933336383801235 0.2953021899412117 7 4.734592328343045 0.7683668103299243 0.3018616965520242 8 4.615947451448938 0.7146732344564072 0.2703827738678054 9 4.6803707531212755 0.6638872217894898 0.3025861654997538 10 4.816461764430528 0.723255515717353 0.25670201799333514 11 4.715391202276792 0.7631490611108758 0.2805758972931145 12 4.795736199345541 0.721580931237918 0.28736486485823887 13 4.673443945554531 0.7002757336639982 0.24095953309542162 14 4.626274987663443 0.8515955440488162 0.2821873884297048 15 5.058714287646896 0.8170348497027818 0.2526953182757662 16 4.778088495260491 0.7860796619712214 0.24518207992925956 17 4.744266982976581 0.7992176105346265 0.2936915992063249 18 4.521226047853721 0.7369558098729342 0.253394782476395 19 4.749511717172398 0.70262070529971 0.2554945847214243 20 4.820915366711275 0.7682776544420327 0.26076037533742413 21 4.55223688520381 0.7584627377261918 0.3018286941990943 22 4.772718407150934 0.7750065806718318 0.28653508126785043 23 4.7282092643222855 0.7700269343881351 0.30239221943962125 24 4.5938190331647455 0.6573038602730502 0.2591568709173291 25 4.7763099822656185 0.7397549143614615 0.29008587359676985 26 4.66489233900105 0.7295573261083991 0.2893963239424 27 4.966735466296449 0.8137439981267501 0.2633405851058541 28 4.902587442471245 0.7554157510954284 0.24253385668611127 29 5.061999097833247 0.8107054990191314 0.263160900180179 30 4.644631340643849 0.7290889624399676 0.28900571946358566 31 4.6843594635794155 0.8062280075934336 0.32156198607311526 32 4.827459625338272 0.7311524066809185 0.26922437664953036 33 4.624069566505804 0.7123387654587955 0.2922297777966961 34 4.645471952638884 0.7054784341125041 0.3084832474529865 35 4.824707795173353 0.7722240769224628 0.2695061309919141 36 4.892037909657498 0.8171302561603724 0.21363504800332656 37 4.7173402395887996 0.7537903125917638 0.24389310656868401 38 4.656245774205611 0.6938619474930652 0.29157790156658936 39 4.517981213066607 0.8160031206300115 0.33324367771845365 40 4.953653556168846 0.8341560473813138 0.260490785488095 41 4.886870187835599 0.771188728732947 0.30715009977367635 42 4.7723806263548 0.8381309480667684 0.2670148561435428 43 4.8663892869991034 0.7429879386705789 0.3354337606679425 44 4.7059724018582685 0.8481377071237093 0.2595692773609668 45 4.894882876778416 0.7387582092124221 0.29241834738005756 46 4.685492084324704 0.7719547323688105 0.276965778025169 47 4.737294772456639 0.7537666733917531 0.27303952094226813 48 4.659839870585505 0.7618528566934699 0.20994802978796323 49 4.463066000100186 0.7010905053916221 0.2914288851463671 50 4.778296642879795 0.7791053119003419 0.2913931705435445 51 4.736483584472185 0.6910039773604029 0.2576862723234431 52 4.5969023445517845 0.7000264678496416 0.325594602680774 53 4.671854773127848 0.7214496792373694 0.27805809818850336 54 4.633095536802445 0.6869669135958711 0.30043162306819093 55 4.781848272832184 0.7428119802312884 0.2737873144700762 56 4.643101489055853 0.7844912389774537 0.2862824630997487 57 4.610822346796753 0.7315906761401083 0.29355997331864525 58 4.453632342381665 0.6653941744454747 0.280152307017022 59 5.025762638915332 0.7386193556053027 0.25714369711984286 60 4.673121144363763 0.7661856286947287 0.26723377973779805 61 4.944291438510849 0.7613152244213204 0.29683586039302556 62 4.700465152079221 0.7532747225611995 0.27080823889214767 63 4.807220732655494 0.791819506894833 0.25417312586134966 64 4.880481171170135 0.7607415256902903 0.2461244584963087 65 4.544389222550479 0.6083942559604791 0.2651643493197611 66 4.727948658875329 0.7648413883992138 0.2788123627558744 67 4.759728602279742 0.7881534499798203 0.2587642902716544 68 4.607735647791612 0.6727454255404486 0.27093512544460685 69 4.527459031883146 0.7804612396868765 0.30463020360711346 70 4.694777971455927 0.7408737966283413 0.2843513310463256 71 4.693674298174555 0.6923911779140206 0.2554291553164716 72 4.646144736263198 0.6962746661690188 0.33706700187155725 73 4.793678788863368 0.6977499647451547 0.30908506485957377 74 4.606953620621117 0.7728430123875834 0.33839243137480535 75 4.712733081367464 0.6964652552022115 0.3053868619194354 76 4.675231866515483 0.7153002613723916 0.2673178444763582 77 4.566926430105814 0.7830110493989665 0.333165351422101 78 4.792288638035897 0.7626887981760281 0.24097633849696498 79 4.9173127327432615 0.7909155867535035 0.2618728584339136 80 4.705279472304965 0.7628370505916304 0.2842113814239081 81 4.697969453571847 0.722588431455807 0.2420165584187266 82 4.69707732175128 0.6697574303539026 0.2944563886176371 83 4.636563975768763 0.7033020699870987 0.30112625036368523 84 4.6633685007314485 0.712279079293187 0.29276441987266755 85 4.80944775743525 0.766508559005584 0.2611220427481874 86 4.568209324551937 0.7751152228244109 0.332926042727256 87 4.862288003654831 0.7870679844261698 0.2457451977501457 88 4.64310157015799 0.6349196268464545 0.2870600709951874 89 4.728037514200011 0.8145654756897532 0.30972223081312367 90 4.689060198443285 0.6519064109831149 0.2705609396599171 91 4.970238635533723 0.82092762761496 0.22562945643073773 92 4.565555300380077 0.7737042007616525 0.3014865819522372 93 4.822259981680299 0.7599669670677629 0.2950590695803835 94 4.561417957366509 0.6974409197647625 0.3097736444815625 95 4.781168903238407 0.7399575379339234 0.2615767393977173 96 4.521041074905829 0.6916443427679103 0.2741051877946379 97 4.710187168515469 0.793691577717021 0.28126385206187765 98 4.824251265643184 0.6675766959965985 0.30188488051167206 99 4.61329037578869 0.782325610395661 0.30981842035122154 100 4.7504735521492725 0.7761157023104334 0.30702283281143095
# Realizar "validação-cruzada manual" para encontrar a melhor divisão de treino/teste
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=58, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=x, n_estimators=200, min_samples_leaf=6,
min_samples_split=8, max_depth=8)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.453632342381665 0.6653941744454747 0.280152307017022 1 4.446457871277186 0.6623295874919761 0.28036685541999173 2 4.455246736716892 0.66432572449145 0.2796092063399509 3 4.452172942060514 0.6635542190241837 0.2809178751411324 4 4.455572813115152 0.6628660852290766 0.280897719932266 5 4.44442902252782 0.6617239452843332 0.28195033044007733 6 4.4493766592635 0.6636559609447221 0.28012575810587936 7 4.449338213661284 0.6639959892900933 0.27952947784275506 8 4.451262349383353 0.6645551432686617 0.27857933497639 9 4.450880150926915 0.6655336717098889 0.2780390800785246 10 4.449757584077251 0.6647655895334331 0.28014414878355864 11 4.454923561222311 0.6631318324378731 0.2785356385474379 12 4.443835169355539 0.6630198531302623 0.28095151675022667 13 4.446022912676549 0.6617640279063437 0.2824520357669009 14 4.45356742257968 0.6630975278910411 0.27780561892873257 15 4.449085926841039 0.66403086344972 0.28068888503026346 16 4.449981965640934 0.6630041979859806 0.28073942136040386 17 4.445417537717464 0.663706218095292 0.2816428186904876 18 4.447361256502705 0.663301642880372 0.28064580328862 19 4.451445719483305 0.6637919837809922 0.28043952464065636 20 4.457431580078974 0.6664059988119437 0.2788316392173825 21 4.441956065533005 0.6621180953984899 0.28277888454100886 22 4.453079215516044 0.662483345754205 0.27863829296508313 23 4.468490341489686 0.6642585371439631 0.275494433482104 24 4.4477017761501605 0.6622256217155009 0.27935176907353587 25 4.447335071380615 0.6628056410283046 0.2802887474469806 26 4.462871036701699 0.6646445034838544 0.2759023653560595 27 4.449565957486733 0.6647207929994847 0.2802464932982006 28 4.454487064646445 0.6637052401329955 0.27809221546050655 29 4.450278642192172 0.6638951252344653 0.2797733188857052 30 4.4498974598871985 0.6633796630825083 0.2803405084728299 31 4.446301222937246 0.6647697659043765 0.2803842978855674 32 4.453744893890512 0.6642080446678779 0.27960798971356815 33 4.448904638629939 0.6644439651663758 0.2813231689891402 34 4.453507124376639 0.6643495743119316 0.2789770778216515 35 4.4419276753865535 0.6601323874911554 0.28213959004954614 36 4.455095453431265 0.6660393254189962 0.27845075480206716 37 4.449023965357796 0.6631289729477629 0.2819760676491253 38 4.450418023405069 0.6638180319802188 0.2797178325750199 39 4.45148675825389 0.6630436044157243 0.27919512591421736 40 4.447365386000128 0.6626974890637779 0.27960201676191376 41 4.450835514100987 0.6635778910061613 0.28055882136988786 42 4.446222050067541 0.6630769382886427 0.2829638719658163 43 4.453627999240908 0.663811789785648 0.2818419447598731 44 4.454501602249068 0.6643438096604513 0.2788667605320443 45 4.458873604733659 0.662870018304348 0.2772248095290586 46 4.445544650953646 0.6647795345031994 0.28089081312565267 47 4.451476322676273 0.664473483904539 0.27965334488404525 48 4.450922945197926 0.6651177508612026 0.2806906490152806 49 4.450544661977898 0.6633315700859863 0.2800561963657491 50 4.445348724233802 0.6627988501832272 0.2807443542105257 51 4.4436864918633 0.6611773411976579 0.2839960963114263 52 4.4510458594294535 0.6627327767765576 0.27941817689377946 53 4.4459024935205536 0.6626035091888707 0.2811472704722767 54 4.451229556812856 0.6643240160669995 0.278666811149059 55 4.4584033678920365 0.6633769595164528 0.27885073394008786 56 4.4475825335610635 0.6627364411122671 0.280693776766598 57 4.434532532946035 0.6624495012091147 0.2831647198182159 58 4.45259889482444 0.6617964738044999 0.28087894287898896 59 4.455028736749412 0.6642893614413701 0.2798125953230808 60 4.453016849327302 0.662566003603508 0.27997532558278904 61 4.443492512335112 0.6630044798834132 0.2812615879996725 62 4.447091929841175 0.663689541632836 0.2799149003481355 63 4.459394667927228 0.6648713484103547 0.2788521505296043 64 4.46068782305157 0.6645675996261075 0.27725721745552645 65 4.448972563108138 0.6620441822366856 0.2797278700622039 66 4.444875074901903 0.6612575622722655 0.28204356270526665 67 4.450840539154066 0.662614277560867 0.28224543730957685 68 4.442952294341431 0.6622165899021932 0.2816053885457672 69 4.458162234347264 0.6635263915064746 0.2789553323644254 70 4.4513751345689485 0.6653542649414076 0.2783874042569574 71 4.445229754560858 0.6627979151291078 0.2815899822336194 72 4.438882325008601 0.6617693366468479 0.284016736012925 73 4.446662293700614 0.6639244057915794 0.28144961699987114 74 4.446151542445994 0.6633488955925552 0.28025013024982703 75 4.457259669295188 0.6623747469482224 0.27718803139109716 76 4.448161225858308 0.6621187282236884 0.28155249543448635 77 4.442939587014229 0.6625642255524864 0.28054599549561965 78 4.451100327796048 0.6640111484299492 0.28126217043399815 79 4.4516243302820415 0.6640673244411739 0.2788848218561475 80 4.4650488221659295 0.6653553752599441 0.2770939007615174 81 4.461557621965691 0.665732437335996 0.2777897108397286 82 4.4574118166655765 0.6655880247718795 0.2794026816783103 83 4.451133300214106 0.6637737818702629 0.2791144431694267 84 4.439707813218791 0.6609460623605179 0.2822053533372806 85 4.441267536793291 0.6609492188920035 0.28023170801651576 86 4.448214867944992 0.663168580910246 0.27896305856906845 87 4.448814273136202 0.6633937135823248 0.28018154568545817 88 4.450618489109722 0.664692247403354 0.27950312421550083 89 4.444996496687628 0.6625669927243047 0.2833373613808493 90 4.457484615352496 0.6647469446854034 0.27976465553064067 91 4.458055286553615 0.6649138986591073 0.2779625980125182 92 4.449567615174529 0.6631804897655652 0.2812999171819709 93 4.450836129334851 0.6635602637362926 0.28108941781551866 94 4.445420787069265 0.6624503595439108 0.2796993764955128 95 4.45164853401994 0.6631097411483924 0.2793061964471758 96 4.446612524255602 0.6628363757828692 0.2818459136242598 97 4.442999148455001 0.662897615328537 0.2824958824209488 98 4.457113197358399 0.6640069265789175 0.2806755115362699 99 4.452702165668257 0.6634670385915936 0.2789061352507828 100 4.440590729476728 0.6614279725074267 0.28178047815236773
# Realizar "validação-cruzada manual" para encontrar a melhor divisão de treino/teste
for x in range(150, 251):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=58, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=100, n_estimators=x, min_samples_leaf=6,
min_samples_split=8, max_depth=8)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
150 4.447514755774699 0.6619400701920445 0.28055633616355613 151 4.446397760026588 0.6618921199938579 0.2807577982957966 152 4.4468961657880275 0.6619519566922103 0.2806822909909006 153 4.447433686167774 0.6621189808851264 0.2806911426978117 154 4.447096993884628 0.6623075231055016 0.2809624349827837 155 4.446568537419048 0.6622828576839904 0.2810567596581286 156 4.447257785500996 0.6623401995734806 0.2810514622784517 157 4.447518038451299 0.6624331292277336 0.28101880637192844 158 4.448019673645248 0.6625717269612851 0.2807466506845957 159 4.447331546130235 0.6624499727391165 0.2808886278606373 160 4.448108777646615 0.6626098508089949 0.2807413060311673 161 4.44947254654824 0.6628320638262007 0.2804769441357683 162 4.448431329473901 0.6627126745923972 0.2806397003894786 163 4.448524670087323 0.6627536652782605 0.28059860963838856 164 4.448746158012304 0.6627281438747339 0.2807087420997293 165 4.448888701695428 0.6629572607911352 0.2806708710026914 166 4.448788636268348 0.6628625951411244 0.28076595047929487 167 4.4478233600518795 0.6628867468511704 0.28086575234535616 168 4.448045014669448 0.6631452737036532 0.2809071400632287 169 4.447577577732399 0.66313604153935 0.2808734053380507 170 4.448128968899801 0.6632449472761431 0.28071849017426465 171 4.448714069051353 0.6632012993186822 0.2807770491776872 172 4.448949424611778 0.6631318895178172 0.28065622407994706 173 4.449254276486124 0.6632423779738233 0.28057540593917196 174 4.447962111177414 0.6630881009364958 0.28104552149774287 175 4.447205347089714 0.6629502260436678 0.2811605642331626 176 4.447518544588595 0.6630211333088754 0.2810586069797386 177 4.447155963940276 0.6629976340442011 0.280951068568674 178 4.44686071995327 0.6629043709481222 0.2809071538138991 179 4.447169023995124 0.6629719828929 0.28086276728008874 180 4.4471279651867635 0.6629996938024949 0.28093382926872623 181 4.446945282536318 0.6629531764414517 0.28080696775631153 182 4.445869713810932 0.6627391906373594 0.28119739421941403 183 4.44569089834095 0.6627108313453174 0.2810985353582658 184 4.446300696073994 0.6626683066493441 0.2808465980886542 185 4.445564217680706 0.6625559276178775 0.2810810124316754 186 4.445559756837898 0.6625516290902966 0.28103737592487754 187 4.444745181043628 0.6623947587762918 0.2812797277071437 188 4.444244926939202 0.6622189580550898 0.2812318420399892 189 4.444245997279133 0.6621309147840644 0.2813238800714791 190 4.444185501466736 0.6620720050386725 0.28116559225479343 191 4.443889214035389 0.662209507511509 0.2811903422000226 192 4.44364929770332 0.6621294926532283 0.2812360977898949 193 4.443117940704107 0.6619809605506094 0.2812874376381538 194 4.443026227539219 0.6618987176598851 0.2811893296551058 195 4.442210636788185 0.6618022870348816 0.28136892630805543 196 4.44182761848004 0.6617714217837324 0.28151659170458687 197 4.441618765756343 0.6616515274622123 0.28140716195028304 198 4.441651862864223 0.6615961855200202 0.28149762931539646 199 4.440774467736596 0.6614158539127729 0.2816364122693772 200 4.440590729476728 0.6614279725074267 0.28178047815236773 201 4.440188344149898 0.6613379540551662 0.28180442019281293 202 4.439856032189412 0.6613977598886173 0.2819559636765713 203 4.438999621925768 0.6613811758982965 0.28227187908560913 204 4.439854206684627 0.6615124200598075 0.2819863742107972 205 4.439854258770203 0.6615580568617239 0.28198377202010605 206 4.43942532617479 0.6614998271224787 0.28211257250288646 207 4.439481600870744 0.6616110559859568 0.28201899255850493 208 4.438923403944233 0.6614827162081305 0.28225273427187203 209 4.438766523260049 0.6614753420388739 0.28219680210338094 210 4.438425023596305 0.661298966272837 0.2822645087083693 211 4.438136740184498 0.6613651785489567 0.282274091893445 212 4.437486410056347 0.6611931153333226 0.2825396764819037 213 4.437409182766731 0.6610978388649795 0.2826370825718443 214 4.437841984311654 0.6610790275535653 0.28258542986364577 215 4.438264741322169 0.6610527505609646 0.28254407021331585 216 4.437281158417168 0.6608931274936242 0.28274740863076486 217 4.437535772302232 0.6609269866269875 0.2826807051475946 218 4.437385963398584 0.6609640572538026 0.28272559425023835 219 4.437785737109449 0.6610996730929629 0.2825820213695862 220 4.437417615387316 0.6610579535113968 0.282622989520651 221 4.436856703619037 0.6609981419014521 0.28271968688698057 222 4.436374432220038 0.660876578436759 0.28288254421996506 223 4.436182965232579 0.660856925573142 0.28300039590820436 224 4.436131463862011 0.6607845979317301 0.28299507171090676 225 4.4363344682338 0.6607776294060075 0.2831233771767808 226 4.436107329584298 0.6608121185869305 0.2831340299498778 227 4.436788467410527 0.6607754733007107 0.2828621126592329 228 4.437228133843555 0.6608543241222069 0.2829041905724582 229 4.437303060254067 0.6607506718923714 0.2828260783938499 230 4.437081295335919 0.6607149826944418 0.2829727103672469 231 4.43782059051308 0.6606475271581326 0.2828207376760774 232 4.437906016280067 0.6606341216633409 0.28273454094736905 233 4.43778330394406 0.6605855852874164 0.28272636158417697 234 4.437909031712642 0.6606775139979522 0.2825772849623994 235 4.437629050459175 0.6605788143761729 0.2826040892656656 236 4.43766304540663 0.6605963413307079 0.28259224460063503 237 4.437971394717783 0.6606363839956156 0.28247195468569797 238 4.4376053032559915 0.660776483348671 0.2825486162502948 239 4.438501799053708 0.6609815491058583 0.28229740049528407 240 4.438145305734383 0.6609836961729582 0.2824390029250927 241 4.437798449534031 0.6609404077853558 0.28251632896211654 242 4.4381537023964555 0.6609665845479455 0.2824736689992988 243 4.438478839683927 0.6611143675989969 0.2823965186665903 244 4.438755202920714 0.661071053500195 0.28236043967393265 245 4.439435808153573 0.661186310104112 0.2823301989376231 246 4.439780170030086 0.6612359754186565 0.28224791972752605 247 4.4401347955181345 0.6613467875780533 0.2821070492629938 248 4.439710220097185 0.6612527395247246 0.2821870151527198 249 4.440429800223758 0.6613117054059591 0.2821293736583622 250 4.440584557555172 0.6613590587003711 0.28213637001697267
226 4.436107329584298 0.6608121185869305 0.2831340299498778
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=58, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=x, n_estimators=226, min_samples_leaf=6,
min_samples_split=8, max_depth=8)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.449694175463042 0.6646445486172486 0.2805216027703582 1 4.450408948728824 0.6620699360642753 0.2790589512852474 2 4.454823256717728 0.6646063262484022 0.2798349884737996 3 4.453706333368136 0.6635486002533482 0.28026175562528977 4 4.455125757283891 0.6628252618207228 0.2806429503503016 5 4.446941651332842 0.6626206720346918 0.28176292047653373 6 4.446664760049703 0.6633609586266208 0.2810949245463662 7 4.44588437968004 0.6635195346321501 0.2797675652224674 8 4.452960868218076 0.6644351335747076 0.27825204321281005 9 4.447632145871342 0.6643578593196162 0.27951254735903364 10 4.453116356517457 0.6647060564426679 0.27967661284220413 11 4.454015179730274 0.6632930879038381 0.2790914588474124 12 4.4416308273560094 0.6625601189679305 0.28163190780507186 13 4.445112904229248 0.6618273043939158 0.2825799043462127 14 4.450136510069577 0.6621713744926239 0.27975456453050696 15 4.445931393624817 0.6634296172517252 0.2813163718967393 16 4.4476249981056935 0.6627428919066238 0.28133883009278726 17 4.449109623725429 0.6637771803413455 0.2806334537006282 18 4.447722396943108 0.6639206299619645 0.2810632927185819 19 4.450052023900226 0.6632042890108943 0.2808195689742584 20 4.4542294584210795 0.6659627349661638 0.2789688006471187 21 4.448978625677022 0.6636878817529599 0.28096538042688846 22 4.454832650785485 0.6628711335561785 0.27830710369820144 23 4.46562944241058 0.6638902384871946 0.2757956807857137 24 4.452446222452101 0.6630187079309817 0.27881798070974306 25 4.444501796869874 0.6623382207493768 0.2803680077658298 26 4.460878648553099 0.6648189252662119 0.2768090719702755 27 4.448023744398808 0.6640490016997918 0.2801580517876011 28 4.452961735205822 0.6628505338147881 0.27851474452730196 29 4.450022770517897 0.6637333033421391 0.27967945511412007 30 4.447375879981551 0.6626980777908672 0.2804231373549455 31 4.4454341908465285 0.6640343286187088 0.27993376414087245 32 4.45179515475071 0.6637242881485657 0.2805945897521481 33 4.44996738596754 0.6650180984784918 0.281110134815422 34 4.455302700402266 0.6645417022621696 0.2784108917180428 35 4.446146152142393 0.6614784361012608 0.281737746374113 36 4.456030862564259 0.6662257847637304 0.27808766116651285 37 4.449849166721582 0.6632910086189003 0.2813738649419143 38 4.446947313998732 0.6632076879826154 0.280631513583009 39 4.448848033519579 0.662926611639707 0.2794930824757247 40 4.449569088060331 0.6629434150257587 0.2793801125807146 41 4.44947898678008 0.6637693182620115 0.28068116299821433 42 4.447802341690976 0.663188063722941 0.28289236040206267 43 4.452844881110809 0.6635140001619922 0.2817423305265352 44 4.450215386714139 0.6634110947007774 0.279668114175722 45 4.463040440857717 0.6633171084731647 0.276704175595874 46 4.447025430106112 0.6651135653492696 0.2805497774183918 47 4.454800540328621 0.6651461985481402 0.27836737331122297 48 4.449254207447082 0.6648746415724635 0.28166345967729123 49 4.447778607356695 0.6624830928045058 0.28069124593313977 50 4.445370129237976 0.6624702764001725 0.28073920917941564 51 4.445730735858113 0.6616304770128574 0.2832508061665766 52 4.45345064124562 0.663369119434865 0.27972213757565634 53 4.445367470349589 0.6628187831049216 0.2812405440311876 54 4.449647102178445 0.6643821650613869 0.27961908192047713 55 4.4614136664681885 0.664406051231241 0.2787754797179003 56 4.4468169798837 0.6622592295080043 0.2803335172227749 57 4.435162322884189 0.6619968396146547 0.2830969774161747 58 4.45498048174812 0.6626999096842631 0.280441267137472 59 4.454981415135769 0.6641636839489627 0.2796730458977741 60 4.453647689615414 0.6630932859142774 0.2798071861341621 61 4.4458677335579475 0.6631916426560932 0.28109962128869204 62 4.4440222212855955 0.6626535543067942 0.28101785804769497 63 4.457366307467145 0.665216240865145 0.27946191508183704 64 4.458739321561516 0.663676337796999 0.2779692597663779 65 4.448616258603555 0.6617473929243249 0.2798228012700582 66 4.446530851192651 0.6614941159578397 0.2817000657105142 67 4.45100243831239 0.6629054067953293 0.28185949328672755 68 4.4433786016616965 0.6619446869638362 0.28206336928651266 69 4.455107253749633 0.6629583465797327 0.28005598924647845 70 4.4559591256075315 0.6659460523708582 0.27755025073380324 71 4.445269868586686 0.6625531261096672 0.2814082073682733 72 4.439631536158369 0.6622999664319305 0.28324716338625944 73 4.448669013940169 0.6644800877196617 0.2814742771870665 74 4.44934598253996 0.6637482158504876 0.27947827440206585 75 4.455663087656064 0.6625080091797748 0.2778691135226441 76 4.448974959494643 0.6627803640750248 0.2809708431874022 77 4.4466551509857855 0.6631862607913395 0.2800371060875899 78 4.451458866953701 0.6641605771153836 0.28095948760108835 79 4.453405410295626 0.6641887835259752 0.2786059092173785 80 4.461617466682069 0.6651161606923996 0.2774534895064885 81 4.46051518521993 0.6661468530907751 0.27749676143683666 82 4.454349703918819 0.6651925174458594 0.2803283483817378 83 4.452315303605234 0.6639513784571859 0.2784087454041234 84 4.439533833487593 0.6611974580629089 0.2823027115783918 85 4.443523892976462 0.6613064040926551 0.27988333814390864 86 4.449982547228591 0.6633633191618148 0.27918637777498934 87 4.447809265449085 0.6633336056717904 0.28044872212922356 88 4.447989560719564 0.663183340147892 0.28045828456362454 89 4.448535211866694 0.6631882483442413 0.28198877493948893 90 4.455791604120806 0.6642345076533748 0.27990953400734975 91 4.457548028598176 0.6646838610917112 0.2784262182027367 92 4.4500465977304495 0.6632397462157887 0.28172985584800503 93 4.4496215430277015 0.6636497684726154 0.2815393411114352 94 4.446883689838894 0.6629497646649114 0.2798413188424552 95 4.450581401460398 0.6633665591739423 0.2796101228838339 96 4.442503274877407 0.662758629634263 0.28276077773237385 97 4.442640805404076 0.662648684802428 0.28202428912704003 98 4.457095250973347 0.6644352560059005 0.2808441365703749 99 4.450857696443155 0.6634314296398591 0.27929123904436925 100 4.436107329584298 0.6608121185869305 0.2831340299498778
# Definindo os hiperparâmetros que gostaríamos de sintonizar
param_grid = {
'max_depth': [7, 8, 9],
'min_samples_split': [7, 8, 9],
'min_samples_leaf': [6, 7, 8]
}
# Criando o modelo RandomForestRegressor
rf = RandomForestRegressor(random_state=100, n_estimators=226)
# Criando um objeto GridSearchCV
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2)
# Ajustando o modelo aos dados de treinamento
grid_search.fit(X_train, y_train)
# Obtendo o melhor modelo
best_rf = grid_search.best_estimator_
# Avaliando o modelo nos dados de teste
test_score = best_rf.score(X_test, y_test)
print("Melhores hiperparâmetros encontrados:", grid_search.best_params_)
print("Desempenho do modelo nos dados de teste:", test_score)
Fitting 5 folds for each of 27 candidates, totalling 135 fits
Melhores hiperparâmetros encontrados: {'max_depth': 7, 'min_samples_leaf': 8, 'min_samples_split': 7}
Desempenho do modelo nos dados de teste: 0.29501991964825447
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=x, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=100, n_estimators=226, min_samples_leaf=8,
min_samples_split=7, max_depth=7)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
print(x, mae_model)
0 4.771563714542049 1 4.524267277566529 2 4.734166111531268 3 4.7559493736127 4 4.581761927979131 5 4.753443483559956 6 4.7882679828144 7 4.718404677120305 8 4.584826490764717 9 4.6401668243924945 10 4.773025788143459 11 4.68751586778444 12 4.762643842750319 13 4.640856674988653 14 4.597576641485102 15 5.041739874397266 16 4.736068039188143 17 4.730991974107858 18 4.5059343719013905 19 4.722368971145586 20 4.785876927101026 21 4.511464108655428 22 4.763793865873964 23 4.697877343108457 24 4.55720819172533 25 4.731439963247486 26 4.6546383823744275 27 4.915252057006319 28 4.878914778780205 29 5.012004380009801 30 4.621533622219846 31 4.664152945967335 32 4.794322349682057 33 4.598089835708841 34 4.608526983342184 35 4.773946492502793 36 4.854801219544823 37 4.665737319268308 38 4.64346655557479 39 4.48734982028098 40 4.899518841544344 41 4.842704168713981 42 4.7589096075273885 43 4.839910111424296 44 4.696055892628828 45 4.85472360422356 46 4.658523238546541 47 4.692396020047711 48 4.6158154080948 49 4.460827103737532 50 4.74795868712579 51 4.71767796801681 52 4.5874743873669575 53 4.643660839102164 54 4.593075788454462 55 4.764202813640263 56 4.596370020636657 57 4.580693787802577 58 4.40218699258842 59 5.008236429971466 60 4.635095827290419 61 4.928525931333427 62 4.688415863222476 63 4.7831793753430905 64 4.859732820450487 65 4.533549704944801 66 4.699980415483571 67 4.745449957606453 68 4.584047190846868 69 4.476245793591532 70 4.68008454826889 71 4.666368459203149 72 4.612697009414195 73 4.7794905352792005 74 4.572729091171197 75 4.695550125688163 76 4.646633297811697 77 4.521529663321252 78 4.776450963279037 79 4.878378100233684 80 4.669290140652411 81 4.636379399024125 82 4.6757296776518995 83 4.6076489574143995 84 4.6406440261924295 85 4.768823824986652 86 4.539809522506581 87 4.822156307563899 88 4.619758536845735 89 4.673703741452708 90 4.635010172596739 91 4.929874325534901 92 4.5029646330811275 93 4.783010620554083 94 4.537465547395668 95 4.757852672349017 96 4.496275827900704 97 4.669036438630141 98 4.806856393709623 99 4.580745420548504 100 4.707767953175495
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=58, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=100, n_estimators=226, min_samples_leaf=8,
min_samples_split=7, max_depth=7)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(mae_model, mape_model, r2_model)
4.40218699258842 0.6573448232562745 0.29501991964825447
for x in range(101):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=58, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=x, n_estimators=226, min_samples_leaf=8,
min_samples_split=7, max_depth=7)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(x, mae_model, mape_model, r2_model)
0 4.416308145906402 0.661268905146599 0.2922693809115826 1 4.412742423223239 0.6582673407477443 0.29219632593223555 2 4.417678196717299 0.6605356603901932 0.2923155749731857 3 4.417795118827826 0.6600770377659047 0.29257571441051566 4 4.414094438163307 0.6594068831006079 0.2934135784249958 5 4.411751953545019 0.6596046258192553 0.29300288979896305 6 4.406178907738294 0.6584172725207785 0.29448844943329455 7 4.41470502233921 0.6602815071323389 0.292553108699087 8 4.416334566386545 0.6614781252545426 0.2911801320232267 9 4.411296665276012 0.659955160075166 0.2925095777537897 10 4.420762921129738 0.6612321518340607 0.29116139737288405 11 4.416588325823248 0.6591639716231424 0.2916845030457764 12 4.401455990902037 0.6589232683321427 0.29526146772256046 13 4.41536426340793 0.6606250517923299 0.29283206171818965 14 4.416296116107156 0.6591475047412286 0.2916021146049782 15 4.418201679236689 0.661287778229791 0.29262694736952743 16 4.420432550136122 0.6599769001645117 0.2919906430819764 17 4.412762943175839 0.66030231219235 0.29325174949359 18 4.4052040300195365 0.6583027188044859 0.294566186362873 19 4.41308614507213 0.6598468177210749 0.2926987310609267 20 4.410567633778647 0.6603351112943124 0.29336750560171254 21 4.421972983805405 0.6619067757251803 0.29154709268756773 22 4.417621311078021 0.6603686022006895 0.2912073563606261 23 4.426153292967702 0.6604989293505394 0.28892092760605115 24 4.406823372238105 0.6588858364927369 0.2948713770925241 25 4.414359736074752 0.6595588517861556 0.2909251924345576 26 4.41732240209484 0.6601098919818885 0.2907540695398375 27 4.414334246727429 0.6617475479143515 0.2918738738321609 28 4.421203443080683 0.6607594518808599 0.29004363717989834 29 4.413728316897344 0.6609960720813893 0.291952821372231 30 4.414515875885531 0.6593913710283796 0.29294880903126097 31 4.410403839415078 0.660476121467663 0.29303016737322374 32 4.4126061243283266 0.6596807835604914 0.29334778672861617 33 4.409230742039085 0.6599851891390639 0.29546482911293004 34 4.4187493345204825 0.6611306724869932 0.2915658481619674 35 4.413414082445631 0.6586184173240598 0.2928302430479528 36 4.4135479190248335 0.6601966586902535 0.29284362635288086 37 4.415726872111525 0.6613201523574823 0.29255051202882376 38 4.411841302627304 0.6604656961777358 0.293817999066356 39 4.416079117423773 0.6605134040751734 0.29179740731021475 40 4.415093854109021 0.6600548954588048 0.2919560221679206 41 4.4178670754397436 0.6609245957240307 0.29193699474129475 42 4.413767442208568 0.6609450877593894 0.2942433367479579 43 4.413338366982838 0.6596169616435517 0.29331518157916747 44 4.4127730831954635 0.659711983876151 0.2924441343321782 45 4.418453190957436 0.6591541384801254 0.29153547067020336 46 4.416469792674882 0.6622120995701525 0.291323455637293 47 4.415116832544465 0.6610458978586812 0.29118764766830274 48 4.408954949631578 0.6603311790940474 0.2931841241311348 49 4.407732059853388 0.658410263023049 0.2936395422175515 50 4.4122626465142 0.660042867041073 0.29222115668597903 51 4.407905620750889 0.6590265580890561 0.29490548430198993 52 4.4126229280046765 0.6595135269460979 0.2930162616021591 53 4.405025012049913 0.6586238454909344 0.2946160621167909 54 4.409412121632916 0.660632467338251 0.2928126184164167 55 4.425633050201658 0.6608462663279587 0.29132794796604555 56 4.41076357766364 0.6590411199828791 0.29206900933926827 57 4.409561570233866 0.6595261788701104 0.29323512825897025 58 4.41237037254444 0.6589582707640308 0.2935057746580749 59 4.415204033969992 0.6609189570873218 0.29236561281623175 60 4.4168909861741765 0.6598180037059141 0.2920647059756084 61 4.40849655895043 0.6591108846502576 0.29405251457161585 62 4.409395129138494 0.6596332653582587 0.2934741886424572 63 4.417216611153567 0.6622427235652562 0.29312761151411115 64 4.419133297531372 0.6601165770857367 0.2914194747128689 65 4.411744088266918 0.6581779786100973 0.2930189397648503 66 4.406120352319199 0.6584902761105351 0.2949068916006756 67 4.413598746932932 0.6590553108532643 0.29422603689976334 68 4.407388663849961 0.6584856687926629 0.29331840881690385 69 4.4163979135198765 0.6593486323526558 0.2939953861314364 70 4.418740507342383 0.6627914142443613 0.2904380882599453 71 4.4138772864812434 0.6598494706056638 0.2936634501302535 72 4.40686695722949 0.6590836592226678 0.2947854194988726 73 4.411061758886918 0.6609303634641266 0.29384456495356515 74 4.411040893747445 0.6599704859399314 0.2936066437716257 75 4.417231446867098 0.6597919627645166 0.2912093583222869 76 4.410957369937565 0.6590613135103314 0.2938218987651765 77 4.406761638585495 0.6594656944091335 0.29346283209052304 78 4.423628805472084 0.6604863188670884 0.29002868061230724 79 4.419084218681859 0.6607788833814772 0.29095404216253495 80 4.417192039192114 0.6601412577086861 0.29249184211892565 81 4.424471155559643 0.6630527050511059 0.2903531857490198 82 4.414567387006932 0.6607877329556862 0.29303011254634104 83 4.4132678611988005 0.6602135043059962 0.29157113100950416 84 4.409661916136969 0.6588082071827939 0.2933580276026416 85 4.4134747535959615 0.6586344315136592 0.2919252253993415 86 4.41397065278647 0.6599979909024511 0.2929129499723967 87 4.413611386876806 0.6599623906347949 0.29218723058859597 88 4.415435730300808 0.6602546193956942 0.2926856570889681 89 4.413916749094199 0.6605339741272638 0.29393848526498156 90 4.419615154964505 0.6612130007619925 0.2920709127992335 91 4.419066210400279 0.661296469908861 0.29157806103916795 92 4.4122133196252715 0.6596671080883275 0.29536358912069727 93 4.411551774308853 0.6612032493892729 0.2937667877574821 94 4.413160570551016 0.6603036220264187 0.2925794212542788 95 4.418014481152109 0.6605026454016656 0.29104436668524203 96 4.410281113014535 0.6601789618988232 0.29439745709690723 97 4.409263940774189 0.6596190331043812 0.29405170729145913 98 4.417513174053783 0.6605410274356496 0.29248206875910177 99 4.416688398950841 0.6596125062032081 0.29197038103740225 100 4.40218699258842 0.6573448232562745 0.29501991964825447
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=58, test_size=0.2)
# Treinar o modelo com melhores parâmetros
model = RandomForestRegressor(random_state=100, n_estimators=226, min_samples_leaf=8,
min_samples_split=7, max_depth=7)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Avaliar a performance do modelo em dados "não-vistos" com diferentes métricas
mae_model = mean_absolute_error(y_test, y_pred)
mape_model = mean_absolute_percentage_error(y_test, y_pred)
r2_model = r2_score(y_test, y_pred)
print(mae_model, mape_model, r2_model)
4.40218699258842 0.6573448232562745 0.29501991964825447
media = y_train.mean()
medias = [media] * len(y_test)
mae_mean = mean_absolute_error(y_test, medias)
mape_mean = mean_absolute_percentage_error(y_test, medias)
r2_mean = r2_score(y_test, medias)
print(f'MAE Média: {mae_mean}')
print(f'MAPE Média: {mape_mean}')
print(f'R2 Média: {r2_mean}')
# Visualizar valores reais, média e previsões
plt.plot(np.arange(len(y_test)), y_test, label='Valor Real', alpha=0.5)
plt.plot(np.arange(len(y_test)), medias, label='Média', alpha=1)
plt.plot(np.arange(len(y_test)), y_pred, label='Previsão', alpha=0.5)
plt.legend();
MAE Média: 5.378551016413612 MAPE Média: 0.9520479637346174 R2 Média: -0.004944696958585126
# Extrair a importância das features
importancias = model.feature_importances_
# Criar um DataFrame com as importâncias das features
importancias_df = pd.DataFrame({'Feature': X.columns, 'Importância': importancias})
# Ordenar as features pela importância
importancias_df = importancias_df.sort_values(by='Importância', ascending=False)
# Exibir as melhores variáveis
print("Melhores variáveis para o modelo RandomForestRegressor:")
print(importancias_df)
Melhores variáveis para o modelo RandomForestRegressor:
Feature Importância
5 hora_pico 0.43
3 horas 0.23
0 semana 0.10
1 dia 0.10
2 dia_semana 0.07
4 dia_pico 0.07
y_pred = [round(p) for p in y_pred]
df0 = pd.DataFrame()
df0['quantidade'] = y_test
df0['previsao'] = y_pred
df1 = pd.concat([df0, X_test], axis=1)
colunas = ['semana', 'dia', 'dia_semana']
_ = df1.groupby(colunas)[['quantidade', 'previsao']].sum().reset_index()
_
| semana | dia | dia_semana | quantidade | previsao | |
|---|---|---|---|---|---|
| 0 | 1 | 1 | 3 | 22 | 23 |
| 1 | 1 | 2 | 4 | 6 | 19 |
| 2 | 1 | 3 | 5 | 8 | 9 |
| 3 | 1 | 4 | 6 | 25 | 20 |
| 4 | 2 | 5 | 0 | 36 | 37 |
| ... | ... | ... | ... | ... | ... |
| 325 | 52 | 26 | 5 | 24 | 38 |
| 326 | 53 | 28 | 0 | 24 | 28 |
| 327 | 53 | 29 | 1 | 19 | 52 |
| 328 | 53 | 30 | 2 | 16 | 36 |
| 329 | 53 | 31 | 3 | 76 | 40 |
330 rows × 5 columns
mae = mean_absolute_error(df1['quantidade'], df1['previsao'])
mae
4.394383394383395
# Visualizar valores reais, média e previsões
medias = [df1['quantidade'].mean()] * len(df1)
plt.plot(np.arange(len(df1)), df1['quantidade'], label='Valor Real', alpha=0.5)
plt.plot(np.arange(len(df1)), medias, label='Média', alpha=1)
plt.plot(np.arange(len(df1)), df1['previsao'], label='Previsão', alpha=0.5)
plt.legend();
Rede Neural Artificial Recorrente¶
# Carregar os dados
df = pd.read_excel('pizzaria_limpo.xlsx')
df = df[['data', 'hora', 'quantidade']]
# Converter colunas 'data' e 'hora' para tipo datetime
df['data'] = pd.to_datetime(df['data'])
df['hora'] = pd.to_timedelta(df['hora'])
# Combinar colunas 'data' e 'hora' em uma única coluna de data e hora
df['data'] = df['data'] + df['hora']
# Remover a coluna 'hora'
df.drop(columns=['hora'], inplace=True)
# Definir a coluna 'data' como o índice
df.set_index('data', inplace=True)
# Usar resample por hora e somar as quantidades
df = df.resample('h').sum()
df
| quantidade | |
|---|---|
| data | |
| 2015-01-01 11:00:00 | 6 |
| 2015-01-01 12:00:00 | 17 |
| 2015-01-01 13:00:00 | 33 |
| 2015-01-01 14:00:00 | 15 |
| 2015-01-01 15:00:00 | 14 |
| ... | ... |
| 2015-12-31 19:00:00 | 23 |
| 2015-12-31 20:00:00 | 17 |
| 2015-12-31 21:00:00 | 7 |
| 2015-12-31 22:00:00 | 1 |
| 2015-12-31 23:00:00 | 1 |
8749 rows × 1 columns
from keras.models import Sequential
from keras.layers import LSTM, Dense
from sklearn.preprocessing import MinMaxScaler
# Normalizar os dados
scaler = MinMaxScaler()
data_normalized = scaler.fit_transform(df)
# Função para criar sequências de entrada e saída
def create_sequences(data, sequence_length):
X, y = [], []
for i in range(len(data) - sequence_length):
X.append(data[i:i+sequence_length])
y.append(data[i+sequence_length])
return np.array(X), np.array(y)
# Definir o comprimento da sequência (por exemplo, 24 horas)
sequence_length = 24
# Criar sequências de entrada e saída
X, y = create_sequences(data_normalized, sequence_length)
# Dividir os dados em conjuntos de treinamento e teste
split = int(0.8 * len(X))
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]
# Definir a arquitetura da rede neural
model = Sequential()
model.add(LSTM(units=50, activation='relu', input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(Dense(units=1))
model.compile(optimizer='adam', loss='mse')
model.summary()
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ │ lstm (LSTM) │ (None, 50) │ 10,400 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense (Dense) │ (None, 1) │ 51 │ └──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 10,451 (40.82 KB)
Trainable params: 10,451 (40.82 KB)
Non-trainable params: 0 (0.00 B)
# Treinar o modelo
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_test, y_test))
Epoch 1/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step - loss: 0.0149 - val_loss: 0.0092 Epoch 2/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0086 - val_loss: 0.0108 Epoch 3/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0081 - val_loss: 0.0078 Epoch 4/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0071 - val_loss: 0.0078 Epoch 5/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0068 - val_loss: 0.0074 Epoch 6/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0068 - val_loss: 0.0073 Epoch 7/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0060 - val_loss: 0.0075 Epoch 8/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0066 - val_loss: 0.0073 Epoch 9/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0062 - val_loss: 0.0071 Epoch 10/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0068 - val_loss: 0.0069 Epoch 11/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0061 - val_loss: 0.0069 Epoch 12/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0062 - val_loss: 0.0069 Epoch 13/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0057 - val_loss: 0.0068 Epoch 14/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0063 - val_loss: 0.0069 Epoch 15/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0060 - val_loss: 0.0067 Epoch 16/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0063 - val_loss: 0.0067 Epoch 17/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0061 - val_loss: 0.0067 Epoch 18/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0056 - val_loss: 0.0066 Epoch 19/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - loss: 0.0059 - val_loss: 0.0067 Epoch 20/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0058 - val_loss: 0.0067 Epoch 21/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0060 - val_loss: 0.0064 Epoch 22/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0061 - val_loss: 0.0069 Epoch 23/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0057 - val_loss: 0.0065 Epoch 24/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0060 - val_loss: 0.0065 Epoch 25/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0054 - val_loss: 0.0065 Epoch 26/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0056 - val_loss: 0.0064 Epoch 27/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0060 - val_loss: 0.0066 Epoch 28/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0055 - val_loss: 0.0063 Epoch 29/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0057 - val_loss: 0.0062 Epoch 30/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0057 - val_loss: 0.0062 Epoch 31/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0056 - val_loss: 0.0061 Epoch 32/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0056 - val_loss: 0.0061 Epoch 33/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0055 - val_loss: 0.0063 Epoch 34/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0066 Epoch 35/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0059 - val_loss: 0.0061 Epoch 36/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0054 - val_loss: 0.0062 Epoch 37/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0059 - val_loss: 0.0062 Epoch 38/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0057 - val_loss: 0.0061 Epoch 39/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0061 Epoch 40/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0057 - val_loss: 0.0063 Epoch 41/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0060 - val_loss: 0.0062 Epoch 42/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0055 - val_loss: 0.0060 Epoch 43/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0058 - val_loss: 0.0062 Epoch 44/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0058 - val_loss: 0.0060 Epoch 45/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0054 - val_loss: 0.0063 Epoch 46/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0060 Epoch 47/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0056 - val_loss: 0.0061 Epoch 48/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0056 - val_loss: 0.0059 Epoch 49/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0055 - val_loss: 0.0060 Epoch 50/50 219/219 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0054 - val_loss: 0.0060
<keras.src.callbacks.history.History at 0x1e789db5c70>
# Avaliar o modelo
loss = model.evaluate(X_test, y_test)
print("Erro de teste:", loss)
# Prever quantidades futuras
predictions = model.predict(X_test)
predictions_denormalized = scaler.inverse_transform(predictions)
# Visualizar as previsões
print(predictions_denormalized)
55/55 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.0060 Erro de teste: 0.005984573625028133 55/55 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step [[-0.01616192] [-0.01616192] [-0.01616192] ... [ 7.801877 ] [ 3.258135 ] [-0.13483143]]
# Treinar o modelo com validação
history = model.fit(X_train, y_train, epochs=50, batch_size=32, validation_split=0.2)
# Obter as perdas do treinamento e validação
train_loss = history.history['loss']
val_loss = history.history['val_loss']
Epoch 1/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0052 - val_loss: 0.0060 Epoch 2/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0052 - val_loss: 0.0064 Epoch 3/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - loss: 0.0052 - val_loss: 0.0065 Epoch 4/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0062 Epoch 5/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0063 Epoch 6/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0065 Epoch 7/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0066 Epoch 8/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0064 Epoch 9/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0052 - val_loss: 0.0063 Epoch 10/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0064 Epoch 11/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0052 - val_loss: 0.0068 Epoch 12/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0056 - val_loss: 0.0065 Epoch 13/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0067 Epoch 14/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0049 - val_loss: 0.0065 Epoch 15/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0052 - val_loss: 0.0065 Epoch 16/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0065 Epoch 17/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0070 Epoch 18/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0068 Epoch 19/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0066 Epoch 20/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - loss: 0.0051 - val_loss: 0.0068 Epoch 21/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0055 - val_loss: 0.0066 Epoch 22/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0052 - val_loss: 0.0067 Epoch 23/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0052 - val_loss: 0.0067 Epoch 24/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0066 Epoch 25/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0069 Epoch 26/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0068 Epoch 27/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0055 - val_loss: 0.0065 Epoch 28/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0066 Epoch 29/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0070 Epoch 30/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0047 - val_loss: 0.0072 Epoch 31/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0049 - val_loss: 0.0071 Epoch 32/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0070 Epoch 33/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - loss: 0.0050 - val_loss: 0.0068 Epoch 34/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0069 Epoch 35/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0072 Epoch 36/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0063 Epoch 37/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0048 - val_loss: 0.0070 Epoch 38/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0049 - val_loss: 0.0067 Epoch 39/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0046 - val_loss: 0.0067 Epoch 40/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0071 Epoch 41/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0049 - val_loss: 0.0068 Epoch 42/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0052 - val_loss: 0.0066 Epoch 43/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0067 Epoch 44/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0072 Epoch 45/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0049 - val_loss: 0.0069 Epoch 46/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0070 Epoch 47/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0053 - val_loss: 0.0073 Epoch 48/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0072 Epoch 49/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0050 - val_loss: 0.0069 Epoch 50/50 175/175 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - loss: 0.0051 - val_loss: 0.0074
# Obter as perdas do treinamento e teste
train_loss = model.history.history['loss']
val_loss = model.history.history['val_loss']
# Plotar as curvas de perda
plt.figure(figsize=(10, 6))
plt.plot(train_loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
# Avaliar o modelo
mae = model.evaluate(X_test, y_test)
print("Mean Absolute Error:", mae)
55/55 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.0065 Mean Absolute Error: 0.006436566356569529
# Inverter a normalização das previsões
predictions_denormalized = scaler.inverse_transform(predictions)
# Arredondar os valores das previsões para números inteiros
predictions_integer = predictions_denormalized.round().astype(int)
# Visualizar as previsões como no DataFrame original
print(predictions_integer)
[[0] [0] [0] ... [8] [3] [0]]
# Converter as previsões de volta para números inteiros
predictions_denormalized = scaler.inverse_transform(predictions)
predictions_integer = predictions_denormalized.round().astype(int)
# Criar DataFrame com datas da base de teste
df_test = pd.DataFrame(index=df.index[-len(X_test):])
# Adicionar coluna de quantidades reais
df_test['Quantidade Real'] = df['quantidade'][-len(X_test):].values
# Adicionar coluna de previsões
df_test['Previsões'] = predictions_integer
df_test = df_test.loc[df_test['Quantidade Real'] > 0]
df_test = df_test.iloc[1:]
df_test
| Quantidade Real | Previsões | |
|---|---|---|
| data | ||
| 2015-10-20 12:00:00 | 19 | 18 |
| 2015-10-20 13:00:00 | 23 | 11 |
| 2015-10-20 15:00:00 | 6 | 3 |
| 2015-10-20 16:00:00 | 7 | 11 |
| 2015-10-20 17:00:00 | 19 | 15 |
| ... | ... | ... |
| 2015-12-31 19:00:00 | 23 | 12 |
| 2015-12-31 20:00:00 | 17 | 11 |
| 2015-12-31 21:00:00 | 7 | 8 |
| 2015-12-31 22:00:00 | 1 | 3 |
| 2015-12-31 23:00:00 | 1 | 0 |
829 rows × 2 columns
# Definir as datas como índices do DataFrame
df_test.index = pd.to_datetime(df_test.index)
# Criar o gráfico de duas linhas
plt.figure(figsize=(12, 6))
plt.plot(df_test.index, df_test['Quantidade Real'], marker='o', color='blue', label='Quantidade Real')
plt.plot(df_test.index, df_test['Previsões'], marker='o', color='orange', label='Previsões')
plt.title('Diferença entre Quantidade Real e Previsão')
plt.xlabel('Data')
plt.ylabel('Quantidade')
plt.legend()
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
df_test.head()
| Quantidade Real | Previsões | |
|---|---|---|
| data | ||
| 2015-10-20 12:00:00 | 19 | 18 |
| 2015-10-20 13:00:00 | 23 | 11 |
| 2015-10-20 15:00:00 | 6 | 3 |
| 2015-10-20 16:00:00 | 7 | 11 |
| 2015-10-20 17:00:00 | 19 | 15 |
mae = mean_absolute_error(df_test['Quantidade Real'], df_test['Previsões'])
mae
5.214716525934861
# Obter as perdas do treinamento e validação
train_loss = history.history['loss']
val_loss = history.history['val_loss']
Continua...